HUMBUG logo


HUMBUGers

Feed: rss rdf opml

June 24, 2015

Clinton RoyPyCon Australia 2015 Programme Released

PyCon Australia is proud to release our programme for 2015, spread over the weekend of August 1st and 2nd, following our Miniconfs on Friday 31 July.

Following our largest ever response to our Call for Proposals, we are able to present two keynotes, forty eight talks and two tutorials. The conference will feature four full tracks of presentations, covering all aspects of the Python ecosystem, presented by experts and core developers of key Python technology. Our presenters cover a broad range of backgrounds, including industry, research, government and academia.

We are still finalising our Miniconf timetable, but we expect another thirty talks for Friday. We’d like to highlight the inaugural running of the Education Miniconf whose primary aim is to bring educators and the Python community closer together.

The full schedule for PyCon Australia 2015 can be found at http://2015.pycon-au.org/programme/about

PyCon Australia has endeavoured to keep tickets as affordable as possible. We are able to do so, thanks to our Sponsors and Contributors. Registrations for PyCon Australia 2015 are now open, with prices starting at AU$50 for students, and tickets for the general public starting at AU$240. All prices include GST, and more information can be found at http://2015.pycon-au.org/register/prices

We have also worked out favourable deals with accommodation providers for PyCon delegates. Find out more about the options at http://2015.pycon-au.org/register/accommodation

To begin the registration process, and find out more about each level of ticket, visit http://2015.pycon-au.org/register/prices
Important Dates to Help You Plan

June 29: Financial Assistance program closes.
July 8: Last day to Order PyCon Australia 2015 T-shirts
July 19: Last day to Advise Special Dietary Requirements
July 31 : PyCon Australia 2015 Begins

About PyCon Australia

PyCon Australia is the national conference for the Python Programming Community. The sixth PyCon Australia will be held on July 31 through August 4th, 2015 in Brisbane, bringing together professional, student and enthusiast developers with a love for developing with Python. PyCon Australia informs the country’s Python developers with presentations, tutorials and panel sessions by experts and core developers of Python, as well as the libraries and frameworks that they rely on.

To find out more about PyCon Australia 2015, visit our website at http://pycon-au.org or e-mail us at contact@pycon-au.org.

PyCon Australia is presented by Linux Australia (www.linux.org.au) and acknowledges the support of our Platinum Sponsors, Red Hat Asia-Pacific, and Netbox Blue; and our Gold sponsors, The Australian Signals Directorate and Google Australia. For full details of our sponsors, see our website.


Filed under: Uncategorized

June 24, 2015 03:43 AM

June 23, 2015

Adrian SuttonEnd to End Tests @ LMAX Update

A little while back I said that LMAX ran around 11,000 end to end tests in around 50 minutes. Since then we’ve deployed some new hardware to run our continuous integration on, plus continued building new stuff and are now running about 11,500 tests in under 20 minutes.

A large part of the speed boost is extra VM instances but also the increased RAM allocation available to each VM has allowed us to increase a number of limits in the system and we can now run more tests concurrently against each VM instance.

We’re currently running 61 instances of the exchange using virtual machines hosted by four Dell FX2s chassis three-quarter populated with FC630s. That gives us 480 cores and 4.5TiB RAM. That’s certainly no small investment, but we consider it excellent value for money because of the boost in productivity and confidence it gives our development team (not to mention the boost in confidence and reliability it gives our clients).

June 23, 2015 10:54 PM

June 16, 2015

Ben MartinAbide the Slide

The holonomic drive robot takes it's first rolls! This is what you get when you contort a 3d printer into a cross format and attach funky wheels. Quite literally as the control board is an Arduino Mega board with Atmel 2650 MCU and a RAMPS 1.4 stepper controller board plugged into it. The show is controlled over rf24 link from a hand made controller. Yes folks, a regression to teleoperating for now. I'll have to throw the thing onto scales later, but the steppers themselves add considerable weight to the project, but there doesn't seem to be much problem moving the thing around under it's own power.

<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/DQIhmtbLHjQ" width="560"></iframe>

The battery is a little underspeced, it will surely supply enough current, and doesn't get hot after operation, but the overall battery capacity is low so the show is over fairly quickly. A problem that is easily solved by throwing more dollars at the battery. The next phase is to get better mechanical stability by tweaking things and changing the software to account for the fact that one wheel axis is longer than the other. From there some sensor feedback (IMU) and a fly by wire mode will be on the cards.

<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/YnLRUeyeOUI" width="560"></iframe>

This might end up going into ROS land too, encapsulating the whole current setup into being a "robot base controller" and using other hardware above to run sensors, navigation, and decision logic.

June 16, 2015 10:39 PM

June 12, 2015

Clinton RoyPyCon Australia 2015 Early Bird Registrations Now Open!

We are delighted to announce that online registration is now open for PyCon Australia 2015. The sixth PyCon Australia is being held in Brisbane, Queensland from July 31st – 4th August at the Pullman Brisbane and is expected to draw hundreds of Python developers, enthusiasts and students from Australasia and afar.

Starting today, early bird offers are up for grabs. To take advantage of these discounted ticket rates, be among the first 100 to register. Early bird registration starts from $50 for full-time students, $180 for enthusiasts and $460 for professionals. Offers this good won’t last long, so head straight to http://2015.pycon-au.org and register right away.

PyCon Australia has endeavoured to keep tickets as affordable as possible. We are able to do so, thanks to our Sponsors and Contributors.

We have also worked out favourable deals with accommodation providers for PyCon delegates. Find out more about the options at http://2015.pycon-au.org/register/accommodation

To begin the registration process, and find out more about each level of ticket, visit http://2015.pycon-au.org/register/prices
Important Dates to Help You Plan

June 8: Early Bird Registration Opens — open to the first 100 tickets
June 29: Financial Assistance program closes.
July 8: Last day to Order PyCon Australia 2015 T-shirts
July 19: Last day to Advise Special Dietary Requirements
July 31 : PyCon Australia 2015 Begins

About PyCon Australia

PyCon Australia is the national conference for the Python Programming Community. The sixth PyCon Australia will be held on July 31 through August 4th, 2015 in Brisbane, bringing together professional, student and enthusiast developers with a love for developing with Python. PyCon Australia informs the country’s Python developers with presentations, tutorials and panel sessions by experts and core developers of Python, as well as the libraries and frameworks that they rely on.

To find out more about PyCon Australia 2015, visit our website at http://pycon-au.org or e-mail us at contact@pycon-au.org.

PyCon Australia is presented by Linux Australia (www.linux.org.au) and acknowledges the support of our Platinum Sponsors, Red Hat Asia-Pacific, and Netbox Blue; and our Gold sponsors, The Australian Signals Directorate and Google Australia. For full details of our sponsors, see our website.


Filed under: Uncategorized

June 12, 2015 08:35 AM

June 08, 2015

Adrian SuttonTesting@LMAX – Aliases

Even after a magnum opus on the DSL LMAX uses for acceptance tests, there’s one crucial feature that I haven’t mentioned: the use of aliases to allow tests to use simple, meaningful names while ensuring that uniqueness constraints are met.

Creating a user with our DSL looks like:

registrationAPI.createUser("user");

You might expect this to create a user with the username ‘user’, but then we’d get conflicts between every test that wanted to call their user ‘user’ which would prevent tests from running safely against the same deployment of the exchange.

Instead, ‘user’ is just an alias that is only meaningful while this one test is running. The DSL creates a unique username that it uses when talking to the actual system. Typically this is done by adding a postfix so the real username is still reasonably understandable e.g. user-fhoai42lfkf.

We do the same thing for instruments, venues, currencies and anything else that needs unique names.

This relatively simple trick gives us a great deal of isolation between tests that may run against the same server instance, even allowing us to run the same test multiple times without interfering with itself.

June 08, 2015 02:44 AM

June 05, 2015

Adrian SuttonTesting@LMAX – Abstraction by DSL

At LMAX, all our acceptance tests are written using a high level DSL. This gives us two key advantages:

The DSL that LMAX uses is probably not what most people think of when hearing the term DSL – it doesn’t attempt to read like plain English, just simplifies things down significantly. We’ve actually open sourced the simple little library that is the entrance-way to what we think of as the DSL – creatively named simple-dsl. It’s essentially the glue between what we write in an acceptance test and the plain-java implementation behind that.

As a simple example here’s a test that creates a user, instrument and places an order:

registrationAPI.createUser("user");
adminAPI.marketOperations.createInstrument("instrument");
tradingAPI.login("user");
tradingAPI.placeOrder("instrument", "quantity: 5", "type: market",
"expectedStatus: UNMATCHED");

Overall, the aim is to have the acceptance tests written at a very high level – focussing on what should happen but leaving the how to the DSL implementation. The tradingAPI.placeOrder call is a good example of this, it’s testing that when the user places an order on an instrument with no liquidity, it won’t be matched. In the DSL that’s actually a two step process, first place the order and receive a synchronous OK response to say the order was received, then when the order reaches the matching engine an asynchronous event will be emitted to say the order was not matched. We could have made that two separate calls in the acceptance test but that would have exposed too much detail about how the system works when what we really care about is that the order is unfilled, how that’s reported is an implementation detail.

However that does mean that the implementation of the DSL an important part of the specification of the system. The acceptance tests express the user requirements and the DSL expresses the technical details of those requirements.

Model the Types of Users and Interactions

All our acceptance tests extends a base class, DslTestCase, that exposes a number of public variables that act as the entry points to the system (registrationAPI, adminAPI and tradingAPI in the example above). Each of these roughly represent a way that certain types of users interact with the system. So registrationAPI works with the API exposed by our registration gateway – the same APIs that our sign-up process on the website talks to.  adminAPI uses the same APIs our admin console talks to and tradingAPI is the API that both our UI uses and that many of our clients interact with directly.

We also have UI variants like adminUI and tradingUI that use selenium to open a browser and test the UI as well.

Our system tends to have a strong correlation between the type of user and the entry point to the system they use so our DSL mostly maps to the gateways into our system, but in other systems it may be more appropriate to focus more on the type of user regardless of what their entry point into the system is. Again the focus should be on what happens more than how. The way you categorise functions in the DSL should aid you in thinking that way.

That said, our top level DSL concepts aren’t entirely restricted to just the system entry point they model. For example the registrationAPI.createUser call in the example will initially talk to the system’s registration API, but since a new account isn’t very useful until it deposits funds, it then talks to the admin console to approve the registration and credit some funds into the users account. There’s a large dose of pragmatism involved in the DSL implementation with the goal being to make it easy to read and write the acceptance tests themselves and we’re willing to sacrifice a little design purity to get that (but only a little).

Top level concepts often further categorise the functionality they provide, for example our admin console that adminAPI drives has a lot of functionality and is used by a range of types of users, so it sub-categorises into things like marketOperations, customerServices, risk, etc.

Add Reusable Components to the DSL

One of the signs that people don’t understand the design of our DSL is when they extract repetitive pieces of tests into a private method within the test itself. On the surface this seems  like a reasonable idea, allowing that sequence of actions to be reused by multiple tests in the file. If the sequence is useful in many test cases within one file and significant enough to be worth the indirection of extracting a method it’s almost inevitably useful across many files.

Instead of extracting a private method, put reusable pieces into the DSL itself. Then they’ll be available to all your tests.  More importantly though, you can make that method fit into the DSL style properly – in our case, using simple-dsl to pass parameters instead of a fixed set of method parameters. 

One of our top level concepts in the DSL is ‘workflows’. It bundles together broader sequences of actions that cut across the boundaries of any one entrance point. It’s a handy home for many of the reusable functions we split out. The down side is it’s currently a real grab bag of random stuff and could do with some meaningful sub-categorisation. Naming is hard…

Design to Avoid Intermittency

The way the DSL is designed is a key weapon in the fight against intermittency. The first rule is to design each function to appear synchronous as much as possible. The LMAX Exchange is a highly asynchronous system design but our DSL hides that as much as possible.

The most useful pattern for this is that whenever you provide a setter-type function it should automatically wait and verify that the effect has been fully applied by checking the equivalent getter-type API. So the end of the DSL implementation for registrationAPI.createUser is a waiter that polls our broker service waiting for the account to actually show up there with the initial balance we credited. That way the test can carry on and place an order immediately without intermittently being rejected for a lack of funds.

The second key pattern applies when verifying values. We produce a lot of reports as CSV files so originally had DSL like:

adminAPI.finance.downloadCashflowReport("date: today", "rememberAs: myCsvFile");
adminAPI.finance.verifyCashflowReportContains("csvFile: myCsvFile", "amount: 10.00");

Apart from being pretty horrible to read, this leads to a lot of intermittency because our system doesn’t guarantee that cash flows will be recorded to the database immediately, it’s done asynchronously so is only guaranteed to happen within a reasonable time. Instead it’s much better to write:

adminAPI.finance.verifyCashflowReportContains("date: today", "amount: 10.00");

Then inside the DSL you can use a waiter to poll the cashflow CSV until it does contain the expected value or whatever you define as a reasonable time elapses and the test times out and fails. Again, having the test focus on what and the DSL dealing with how allows us to write better tests.

Don’t Get Too Fancy with the DSL

The first thought most people have when they see our DSL is that it could be so much better if we used static types and chained method calls to get the compiler to validate more stuff and have refactoring tools work well. It sounds like a great idea, our simple string based DSL seems far too primitive to work in practice but we’ve actually tried it the other way as well and it’s not as great as it sounds.

Inevitably when you try to make the DSL too much like English or try to get the compiler more involved you add quite a lot of complexity to the DSL implementation which makes it a lot harder to maintain so the cost of your acceptance tests goes up – exactly the opposite of what you were intending.

The trade offs will vary considerably depending on which language you’re using for your tests and the best style of DSL to create will vary significantly. I strongly suspect though that regardless of language the best DSL is a radically simple one, just that different things are radically simple in different languages.

DSL’s Matter

This was meant to be a quick article before getting on to what I really wanted to talk about but suddenly I’m 1500 words in and still haven’t discussed anything about the implementation side of the DSL.

It turns out that while our DSL might be simple and something we take for granted, it’s a huge part of what makes our acceptance tests easily maintainable instead of gradually becoming a huge time sink that prevents any change to the system. My intuition is that those people who have tried acceptance tests and found them too expensive to maintain have failed to find the right style of abstraction in the DSL they use, leaving their tests too focused on how instead of what.

June 05, 2015 06:34 AM

May 04, 2015

Elspeth ThorneCatching up with myself.

It's been quite a while since my last entry on this blog.

Since then, many things have happened.

Starting with the physical stuff, I'm an inch taller. This is a result of some pretty intense physiotherapy and rehabilitation work. My thoratic spine was frozen in place; that's been addressed, finally, and I'm slowly improving. I've even been able to start addressing my lower and upper spine issues. I have to maintain a pretty extensive stretch and exercise regimen, but even with the DOMS I have less back pain than I have had in decades.

Speaking of, I'm weightlifting twice a week. It's a simple split; generally on Mondays I do squats and assisted chin ups; on Thursdays I do deadlifts and some form of upper-body-push exercise, like a pushup or shoulder press. I got up to a working weight of 55kgs when doing squats (generally in four sets of eight reps). That's a pretty good start. I still have a very long way to go before I'm as strong as I'd like to be, especially in my upper body.

As far as flexibility goes, I can touch my toes most of the time, without extensive warm-up, for the first time in my life. Which is awesome. The downside is that combined with other things, there's a distinct possibility I may also have a hyperflexibility disorder. Apparently, when I'm not frozen up, or have muscular tension blocking things, I bend really really well. Too well. One of the implications is that it takes me a lot more effort to do pretty much anything, because I have to use muscles for support and control rather than ligaments and tendons. Which would also explain why and how I strain muscles so easily and often, and some of the fatigue I deal with. Also why I bruise so easily. The long term implications mean that I'm going to be doing an awful lot of strength training and flexibility/mobility work for as long as it's physically possible, just to maintain the level of functionality most people get from sitting in a chair all day. On the upside, knowing what the situation is makes it a whole lot easier to manage, instead of fumbling around and hoping that something will work.

Pain-wise, well, I'm not in pain 24/7 anymore. There are some weeks where I don't even take any painkillers. Day to day I probably experience more pain than most people, but it's rather less than I was accustomed to at most points, which I am very grateful for.

Mentally speaking - well, I'm on antidepressants again. The grey dog struck with a vengeance last year. Food was tasteless, I couldn't care about anything, especially not my own wellbeing, and things got not so great. I made the decision to address this, and I'm doing rather better, which is nice.

My memory has improved significantly. While I'm not back to my previous level of function, I no longer get lost on the way to places I've been several times before, and my memory for people is also much better. There's an entry of its own in there, but I'll leave that for after this one.

Socially speaking, I actually have a social life again! Which is amazing and wonderful. I miss all my Australian friends, but the isolation over here seems to have ended. I certainly hope it has; I'm pretty good with being solitary, but after 3 years of it, I'd like to be a social butterfly for a while. It hasn't all been sunshine and unicorn farts. Readjusting to being around people has been a little tricky - balancing the sensory overload with actually getting lonely when I can't go out is a current challenge. Still, the awesome new people in my life are more than worth it!

I have yet to take up any form of study. That's annoying, but in all honesty, something that has to wait until I'm sure I have the intellectual, emotional, and physical reserves to not run myself into the ground again. Or to recover when I do so the first few times before I manage to calibrate myself accurately enough.

That's pretty much it for now. I'm hoping that this is the start of me actually writing about my mindstate a little more often, but well, we'll have to see.

May 04, 2015 11:19 AM

May 02, 2015

Clinton RoyOne Week Left for PyCon Australia 2015 Proposals!


Under a week to go – closes Friday 8th May

With just under a week to go until the PyCon Australia 2015 Call for Proposals closes, we thought it would be a good idea to give everyone an update and a reminder. We’re very happy with the proposals we’ve already received, but we’re eager to receive more! We hope our proposal writing working bees in Brisbane have been of help, and hope to roll them out to more cities next year. If you’ve got any questions please get in touch (numerous contact details are up on pycon-au.org). We would like to give a special shout out for the Education MiniConf, which is new this year: if you know people teaching and using computing in the education realm, please forward this CFP on.

The deadline for proposal submission is Friday 8th May, 2015.


Conference

The conference this year will be held on Saturday 1st and Sunday 2nd August 2015 in Brisbane. PyCon Australia attracts professional developers from all walks of life, including industry, government, and science, as well as enthusiast and student developers. We’re looking for proposals for presentations and tutorials on any aspect of Python programming, at all skill levels from novice to advanced.
Presentation subjects may range from reports on open source, academic or commercial projects; or even tutorials and case studies. If a presentation is interesting and useful to the Python community, it will be considered for inclusion in the program.
We’re especially interested in short presentations that will teach conference-goers something new and useful. Can you show attendees how to use a module? Explore a Python language feature? Package an application?

Miniconfs

Four Miniconfs will be held on Friday 31st July, as a prelude to the main conference. Miniconfs are run by community members and are separate to the main conference. If you are a first time speaker, or your talk is targeted to a particular field, the Miniconfs might be a better fit than the main part of the conference. If your proposal is not selected for the main part of the conference, it may be selected for one of our Miniconfs:
DjangoCon AU is the annual conference of Django users in the Southern Hemisphere. It covers all aspects of web software development, from design to deployment – and, of course, the use of the Django framework itself. It provides an excellent opportunity to discuss the state of the art of web software development with other developers and designers.
The Python in Education Miniconf aims to bring together community workshop organisers, professional Python instructors and professional educators across primary, secondary and tertiary levels to share their experiences and requirements, and identify areas of potential collaboration with each other and also with the broader Python community.
The Science and Data Miniconf is a forum for people using Python to tackle problems in science and data analysis. It aims to cover commercial and research interests in applications of science, engineering, mathematics, finance, and data analysis using Python, including AI and ‘big data’ topics.
The OpenStack Miniconf is dedicated to talks related to the OpenStack project and we welcome proposals of all kinds: technical, community, infrastructure or code talks/discussions; academic or commercial applications; or even tutorials and case studies. If a presentation is interesting and useful to the OpenStack community, it will be considered for inclusion. We also welcome talks that have been given previously in different events.

First Time Speakers

We welcome first-time speakers; we are a community conference and we are eager to hear about your experience. If you have friends or colleagues who have something valuable to contribute, twist their arms to tell us about it! Please also forward this Call for Proposals to anyone that you feel may be interested.

The most recent call for proposals information can always be found at: pycon-au.org/cfp

See you in Brisbane in July!

Important Dates

Call for Proposals opens: Friday 27th March, 2015
Proposal submission deadline: Friday 8th May, 2015
Proposal acceptance: Monday 25 May, 2015


Filed under: Uncategorized

May 02, 2015 06:54 AM

April 30, 2015

Adrian SuttonMaking End-to-End Tests Work

The Google Testing Blog has an article “Just Say No to More End-to-End Tests” which winds up being a rather depressing evaluation of the testing capabilities, culture and infrastructure at Google. For example:

Let’s assume the team already has some fantastic test infrastructure in place. Every night:

  1. The latest version of the service is built. 
  2. This version is then deployed to the team’s testing environment. 
  3. All end-to-end tests then run against this testing environment. 
  4. An email report summarizing the test results is sent to the team.

If your idea of fantastic test infrastructure starts with the words “every night” and ends with an email being sent you’re doomed. Bryan Pendleton does a good job of analysing and correcting the details so I won’t recover that ground. Instead, let me provide a view of what reasonable test infrastructure looks like.

At LMAX we’ve recently reached the milestone of 10,000 end to end acceptance tests. We’ve obviously invested a lot of time in building up all those tests but they’re invaluable in the way they free us to try daring things and make sweeping changes, confident that if anything is broken it will be caught. We’re happy to radically restructure components in ways that require lots of changes to unit tests because of those end-to-end tests.

We also have huge numbers of unit tests, integration tests, performance tests, static analysis and various other forms of tests, but the end-to-end tests are far more than a sanity-check, they’re a primary form of quality control.

Those end-to-end tests, or acceptance tests as we call them:

That’s pretty much entry-level for doing end-to-end testing (or frankly any testing). We’ve also got a few extra niceties that I’ve written about before:

Plus the test results are displayed in real-time, so we don’t even have to wait for the end of the test run to see any failures. Tests that failed on the previous run are run first to give us quick feedback on whether they’ve been fixed or not.

There’s lots of great stuff in there, but we have more work to do. We have an intermittency problem. When we started out we didn’t believe that intermittency could be avoided and accepted a certain level of breakage on each build – much like the Google post talks about expecting 90% of tests to pass. That attitude is a death-knell for test reliability. If you don’t have all the tests passing consistently, gradually and inevitably more and more tests become intermittent over time.

We’ve been fighting back hard against intermittency and making excellent progress – we’ve recently added the requirement that releases have no failures and green builds are the norm and if there are intermittent failures it’s usually only one or two per run. Currently we’re seeing an intermittent failure rate of around 0.00006% of tests run (which actually sounds pretty good but with 10,000 tests that’s far too many runs with failures that should have been green).

But improvements come in waves with new intermittency creeping in because it can hide in amongst the existing noise. It has taken and will take a lot of dedication and commitment to dig ourselves out of the intermittency hole we’re in but it’s absolutely possible and we will get there.

So next time you hear someone try to tell you that end-to-end tests aren’t worth the effort, point them to LMAX. We do end-to-end testing big time and it is massively, indisputably worth it. And we only expect it to become more worth it as we reduce the intermittency and continue improving our tools over time.

April 30, 2015 05:46 AM

April 27, 2015

Ben MartinUnbrick the NUC

It seems there are many folks with the suspend of death on the NUC. When you suspend to RAM you can't get back. When you disconnect power for a while you can't turn it on again. Welcome to brickland, population: you. I found that following the advice on the forums if I disconnect the CMOS battery for a bit then I could turn on the NUC again.

The downside is that the CMOS battery is installed under the motherboard, so you have to remove the motherboard which is no easy task the first time. Then each subsequent time that the NUC bricks you have to take it apart again to such a great extent.

Luckily I found these extension leads which let me bring out the battery from the case. So hopefully now a debrick isn't going to involve a system teardown anymore.

April 27, 2015 11:14 AM

April 14, 2015

Adrian SuttonPrinting Only Part of a grep Match

It’s not uncommon to want to find a particular line in a file and print just a part of it.  For example, if we wanted to find the total memory on a machine we could use:

grep '^MemTotal:' /proc/meminfo | 
sed -e 's/^MemTotal:\s*\([0-9]*\).*/\1/'

Which does the job but duplicates a bunch of the matching regex. If you’re using a reasonably recent gnu grep, you can use it’s support for perl regex syntax and the \K operator:

grep -Po '^(MemTotal:\s*)\K[0-9]*' /proc/meminfo

The -P is for perl regex, and the o option causes grep to output only what is matched. You can see though that we’re actually matching the MemTotal: at the start of the line yet somehow it doesn’t wind up in the output.  That’s the magic of \K which excludes the token immediately prior to it from the matched text (without rewinding the stream and attempting a different match for that text).

Update

Alexandre Niveau emailed me to point out that in this particular case (and probably most others where I’d be tempted to use \K with grep) grep is completely superfluous and we can just use sed with the -n flag:

sed -n -e 's/^MemTotal:\s*\([0-9]*\).*/\1/p' /proc/meminfo

The -n disables automatic printing of lines and the ‘p’ at the end of the regex prints the matching lines. Definitely good to know – thanks Alexandre.

April 14, 2015 11:02 PM

April 10, 2015

Ben MartinTiny Tim improves and gets Smaller

I finally switched Tiny Tim over to a lipo battery. Almost everything worked when I tested the new battery, the only thing that failed in a major way were the two 2812 LEDs which, either didn't come on or came on for a very quick moment and went dark. So Tim is now smaller again without the "huge" AA battery pack at it's tail.


The 2812 story was interesting. It wasn't going to be happy jumping to the 7.6v of the 2S lipo. So I tried various voltage divider setups which didn't work either. I ended up using a common 5v regulator and the lights work fine again. I think I was maybe using too high resistor values in the divider and the 2812s didn't like it. At any rate, they apparently want a good regulated power source, and I wasn't giving it one before I switched over to using the regulator.

On the whole, going from 5-6v of the AA pack to 7.6v has made it a snappier mover. I tried it initially with the battery on the bench and found it would lift the back off the desk under hard break.

Next up is probably attaching a claw or drop mechanism and ultrasound sensor and then take on the Sparkfun autonomous ping-pong ball into cup challenge. I'll probably control it via wireless from a second on board micro-controller. The drop, ultrasound, and autonomous navigation micro (and additional battery) can all be put into a single "module" that I can then bolt to Tim. All the navigation micro needs to do is control the differential drive like a remote control would. This way, the existing micro etc on Tim doesn't change at all in order for the challenge to be accepted.


April 10, 2015 01:11 PM

Clinton RoyPyCon Australia 2015 Proposal Writing Working Bee

Writing your first conference proposal can be difficult, so we’re running a working bee at UQ on Saturday 11th (in conjunction with Humbug). If you’ve never written a conference proposal before, or you’d like yours given the once over, please come along, register over at meetup.


Filed under: Uncategorized

April 10, 2015 08:57 AM

April 09, 2015

Adrian SuttonEmoji One – Open source emoji designed for the web.

Mostly so I can find this again later when I inevitably need it, Emoji One is a creative commons licensed collection of Emoji and related tools for the web.

April 09, 2015 12:55 AM

March 30, 2015

Blue HackersSleep: How to nap like a pro | BBC Future

March 30, 2015 11:43 PM

March 28, 2015

Clinton RoyPyCon Australia 2015 Call for Proposals is Open!

PyCon Australia 2015 is pleased to announce that its Call for Proposals is now open!
The conference this year will be held on Saturday 1st and Sunday 2nd August 2015 in Brisbane. We’ll also be featuring a day of Miniconfs on Friday 31st July.

The deadline for proposal submission is Friday 8th May, 2015.

PyCon Australia attracts professional developers from all walks of life, including industry, government, and science, as well as enthusiast and student developers. We’re looking for proposals for presentations and tutorials on any aspect of Python programming, at all skill levels from novice to advanced.

Presentation subjects may range from reports on open source, academic or commercial projects; or even tutorials and case studies. If a presentation is interesting and useful to the Python community, it will be considered for inclusion in the program.

We’re especially interested in short presentations that will teach conference-goers something new and useful. Can you show attendees how to use a module? Explore a Python language feature? Package an application?

Miniconfs

Four Miniconfs will be held on Friday 31st July, as a prelude to the main conference. Miniconfs are run by community members and are separate to the main conference. If you are a first time speaker, or your talk is targeted to a particular field, the Miniconfs might be a better fit than the main part of the conference. If your proposal is not selected for the main part of the conference, it may be selected for one of our Miniconfs:

DjangoCon AU is the annual conference of Django users in the Southern Hemisphere. It covers all aspects of web software development, from design to deployment – and, of course, the use of the Django framework itself. It provides an excellent opportunity to discuss the state of the art of web software development with other developers and designers.

The Python in Education Miniconf aims to bring together community workshop organisers, professional Python instructors and professional educators across primary, secondary and tertiary levels to share their experiences and requirements, and identify areas of potential collaboration with each other and also with the broader Python community.

The Science and Data Miniconf is a forum for people using Python to tackle problems in science and data analysis. It aims to cover commercial and research interests in applications of science, engineering, mathematics, finance, and data analysis using Python, including AI and ‘big data’ topics.

The OpenStack Miniconf is dedicated to talks related to the OpenStack project and we welcome proposals of all kinds: technical, community, infrastructure or code talks/discussions; academic or commercial applications; or even tutorials and case studies. If a presentation is interesting and useful to the OpenStack community, it will be considered for inclusion. We also welcome talks that have been given previously in different events.

Full details: http://2015.pycon-au.org/cfp


Filed under: Uncategorized

March 28, 2015 05:31 AM

March 17, 2015

Ben MartinGoogle Breakpad and the post crash experience

Google Breakpad has many components to it, but at the basic level it lets you capture information at the time a crash occurs and upload that to the net. A really cute part of Breakpad is that the binary doesn't need to have the debug symbols in it, you don't even need to have them on the client machine at any location. When you build version $githash then you use a breakpad tool to copy out the debug symbols into separate files. When the user discovers a crash they upload a minidump file to a server of your selecting. Then you can combine the extracted symbols from build time and the minidump file to generate a backtrace with line number information. So software users don't have to know about gdb or lldb or whatnot and how to make a backtrace and where to paste it.



I recently updated FontForge's use of breakpad to use a small server on localhost to report the bug. The application dmg file for fontforge will soon also include the extracted symbols for the build. By telling breakpad to use a local server, that server can lookup the symbols that are shipped and generate a human readable backtrace with line number information. Because its also a web interface and running locally, it can spawn a browser on itself. So instead of getting the Mac dialog supplied by the osx crash reporter app telling you that there was a crash, you get a web page telling you the same thing. But the web page can use jQuery/Bootstrap (or $ui tool of choice) and ask what the user was doing and offer many ways to proceed from there depending on how the user wants to report things. The https://gist.github.com/ site can be used to report without any login or user accounts. It's also rather handy as a place to checking larger backtraces that might be, maybe, 50-100kb.

But once you can upload to gist, you can get a http and other URL links to the new gist. So it makes sense from there to offer to make a new github issue for the user too. And in that new issue include the link to the gist page so that developers can get at the full backtrace. It turns out that you can do this last part, which requires user login to github, by redirecting to github/.../issues/new and passing title and body GET parameters. While there is a github API, to report a new issue using it you would need to do OAuth first. But in the libre world it's not so simple to have a location to store the OAuth secure token for next time around. So the GET redirect trick nicely gets around that situation.


For those interested in this, the gist upload and callback to subsequently make a github issue are both available. The Google Breakpad hands over the minidump to a POST method which then massages the minidump into the backtrace and spawns a browser on itself. The GET serves up all the html, css, js, and other assets to the browser and that served html/js is what I link to at the start of the paragraph which is where the actual upload/reporting of the backtrace takes place.

The only thing left to do is to respond to the backtraces that come in and everybody gets a more stable FontForge out of the deal. It might be interesting to send off reports to a Socorro server too so that statistics month on month can be easily available.

March 17, 2015 04:33 AM

March 15, 2015

Blue HackersDalek Relaxation for Humans

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="315" src="https://www.youtube-nocookie.com/embed/e59guruVL4o?rel=0&amp;showinfo=0" width="420"></iframe>

March 15, 2015 04:08 AM

March 12, 2015

Clinton RoyThursday 12th March

Walked into work fairly early.

Dead tired by the end of the day.

Signed onto sleepio to give them a burl. Looks like they’d like me to get a fitbit..


Filed under: diary

March 12, 2015 07:47 AM

March 11, 2015

Adrian SuttonPatterns are for People

Avdi Grimm in Patterns are for People:
Patterns aren’t tools for programming computers; they are tools for programming people. As such, to say that “patterns are a language smell” makes very little sense. Patterns are a tool for augmenting language: our language, the language we use to talk to each other about a problem and its solutions; the language we use to daydream new machines in our minds before committing them to code. Patterns aren’t a language smell; rather, patterns are by definition, [optional] language features.
There’s so much we can learn if only we stop making everything into a battle between “new” tools or approaches and “old” ones. Patterns are relevant and useful in all forms of programming and we shouldn’t discard them just because they’re not “cool” anymore. Sadly we seem to throw out nearly all our experience and learning each time a new approach comes along rather than learning from and taking advantage of both.

March 11, 2015 10:01 PM

Clinton RoyWednesday 11th March

Awful day.

Sleep was disrupted by neighbours moving their cars around at two thirty am to make way for builders coming. Why two thirty? fucked if I know.

Finally dragged myself out of bed tired and headachy, headed into work.

Did manage to get some stuff done at work before the jack hammering started, and I left immediately in the early afternoon.

Struggling to stay awake till a sensible hour while catching up on a few of these here diary entries.


Filed under: diary

March 11, 2015 08:16 AM

Clinton RoyTuesday 10th March

Walked home.

Conference stuff.


Filed under: diary

March 11, 2015 08:12 AM

Clinton RoyMonday 9th March

Walked into work stupidly early.

Home early, straight to bed.


Filed under: diary

March 11, 2015 08:12 AM

Clinton RoySunday 8th March

Library day.


Filed under: diary

March 11, 2015 08:10 AM

Clinton RoySaturday 7th March

Coder dojo, much to my surprise I was introducing my simplified markov chain generator. It didn’t get much traction, but I felt that was because most of the kids had something they were interested in doing.

Next week I’m apparently talking all about 3D printing…


Filed under: diary

March 11, 2015 08:10 AM

Clinton RoyFriday 6th March

Deliberately didn’t walk to work as I’m giving blood today.

Stuffing myself silly with food and water, and only one coffee. So much water.

Was vindicated when I gave blood in record time with no dramas, and I didn’t get even a minor bruise at the extraction point.

Stuffed myself silly straight after.


Filed under: diary

March 11, 2015 08:07 AM

Clinton RoyThursday 5th March

Walked to walk stupidly early.

Conference work that night.


Filed under: diary

March 11, 2015 08:04 AM

Clinton RoyWednesday 4th March

The monthly Python Users group meeting. There was a great talk about calculating statistics, like variances, in a single pass.


Filed under: diary

March 11, 2015 08:03 AM

Clinton RoyTuesday 3rd March

Walked home.

Conference stuff.


Filed under: diary

March 11, 2015 08:02 AM

Clinton RoyMonday 2nd March

Was on the motorbike for the first time in a while today. Riding into work very early is great, riding home at peak hour is silly however.


Filed under: diary

March 11, 2015 08:00 AM

Clinton RoySunday 1st March

Conference stuff at The Edge.

Dinner with E. that night.


Filed under: diary

March 11, 2015 07:58 AM

March 05, 2015

Adrian SuttonNew Favourite Little Java 8 Feature

Pre-Java 8:

ThreadLocal<Foo> foo = new ThreadLocal() {
@Override
protected Foo initialValue() {
return new Foo();
}
};

Post-Java 8:

ThreadLocal<Foo> foo = ThreadLocal.withInitial(Foo::new);

Nice.

March 05, 2015 10:03 PM

March 01, 2015

Clinton RoySaturday 28th February

A quite full on day.

Woke up early because..that’s what I do. Headed out to Sunnybank library in the morning, CoderDojo, then back to The Edge for minicomicon, where I picked up a few small freebies, but didn’t spot anything that I felt like buying. I spent a little time coding up a simple Markov generator, hopefully simple enough for the coder dojo folks to follow. After all that, out to Humbug.


Filed under: diary

March 01, 2015 04:43 AM

February 27, 2015

Clinton RoyFriday 27th February

I went to bed really early last night due to my weird ongoing headache. I had a little help getting to sleep. This meant I basically had a full nights sleep by three o’clock. So I ended up walking to work stupidly early and arriving before five am. I still had some residual effects of the whatever-the-heck headache in the morning, but it’s gone by the evening.

The internet was really weird today, llamas and dresses for some reason.

Doing some conf stuff at The Edge. See three friends walk past on the walkway :)


Filed under: diary

February 27, 2015 09:21 AM

February 26, 2015

Clinton RoyThursday 26th February

Another weird day really.

The headache from yesterday did not improve, after physio and tablets. I went to bed early and woke up around 2am with my head still banging.

Work has a construction site across the road and it’s still very noisy at times, it was very difficult dealing with both a headache throbbing inside my head and the builders machines throbbing the outside of my head.

I had lunch offsite with H, who is always doing a million and one things and making me feel lazy.

I decided I didn’t want to deal with the headache and noise in the afternoon and headed home.


Filed under: diary

February 26, 2015 06:31 AM

February 25, 2015

Clinton RoyWednesday 25th February

Bit of an odd day today.

Physio appointment in the morning, specifically looking at my right forearm, I was concerned I was seeing the initial stages of RSI, but the physio relieved those anxiety’s at least. They physio used dry needles to  settle down the muscle that was acting up, that was a first and quite an interesting experience.

Next up I went out to the UQ Market day to rendezvous with the UQCS club, to give them some pamphlets describing PyCon Australia  and Humbug a little. Most of our volunteers last year were UQ students, and I’d be delighted if that were the case again this year.

I’ve ended up with a headache at the end of the day, maybe because I didn’t have any coffee till after lunch?


Filed under: diary

February 25, 2015 08:36 AM

Clinton RoyTuesday 24th February

Walked to work.

While doing some conference stuff, discovered that I hate printers. It took something like an hour to print out two pages of basic text and one image. Whatever pdf version every tool was spitting out, was not handled at all well by either printer.


Filed under: Uncategorized

February 25, 2015 08:29 AM

Clinton RoyMonday 23rd February

Did not walk in today.

Did go and see _Juptier Ascending_ which I really quite liked. If the main baddy wasn’t so completely over the top, I would have quite enjoyed it.


Filed under: diary

February 25, 2015 08:27 AM

February 22, 2015

Clinton RoySunday 22nd February

Waking up at two for no discernible reason.

Breakfast with C was a better start to the morning.

Afternoon at The Edge doing conference stuff.


Filed under: diary

February 22, 2015 04:53 AM

Clinton RoySaturday 21st February

Coder Dojo down at Sunnybank Hill library. Quite exhausting after a bad night’s sleep!


Filed under: diary

February 22, 2015 04:51 AM

Clinton RoyFriday 20th February

Walked to and from work, in an attempt to have a good night sleep tonight..

Tropical Cyclone Marcia has degenerated to a tropical low and is hovering around Brisbane today, making for a lot of rain. I quite like walking in the wet, as long as I’ve got my wet weather gear. Most of the work colleagues are cats and stayed home.

Conference planning later at The Edge.


Filed under: diary

February 22, 2015 03:47 AM

Clinton RoyThursday 19th February

Walked to and from work today.

Doing some conference planning later on.


Filed under: diary

February 22, 2015 03:45 AM

Clinton RoyWednesday 18th February

Walked to work.

Caught up with a C after work, as a surprise thing rather than a planned thing.


Filed under: diary

February 22, 2015 03:43 AM

Clinton RoyTuesday 17th February

A bit of a nothing apart from work day.


Filed under: diary

February 22, 2015 03:42 AM

February 18, 2015

Paul GearonTweaking the Power Limit

After posting the power-limit function earlier I found myself thinking about the inelegance of the expression. I like the approach, but the code seems much more verbose than should be required. In particular, the (partial apply not=) expression seemed too long for something so simple.

As a reminder, here is my last iteration on the function:
(defn power-limit [f a]
  (let [s (iterate f a)]
    (ffirst
      (drop-while (partial apply not=)
                  (map vector s (rest s))))))
The first thing that occurred to me here is the use of vector to pair up the values. It's this pairing that makes the predicate for drop-while more complex. Perhaps I should avoid the pair?

The reason for this pair is so that they can be compared for equality in the next step. So why not just compare them straight away? But that would leave me with a true/false value, when I need to get the values being compared when they are equal. What I really needed was a false/value result, and this reminded me of how a set lookup works. For instance (#{2} 1) returns nil, while (#{2} 2) returns 2. This is what I need, so why not try it?
(defn power-limit [f a]
  (let [s (iterate f a)]
    (first
      (drop-while not
                  (map #(#{%1} %2) s (rest s))))))
The anonymous function in the map looks a little like line noise, but it's not too bad.

Now that the result of map is a value and not a pair, we only need first and not ffirst. The drop-while predicate also gets simpler, just needing a not, but it's still verbose. However, the drop-while is just removing the leading nils from the results of the map, so let's move to keep instead:
(defn power-limit [f a]
  (let [s (iterate f a)]
    (first
      (keep #(#{%1} %2) s (rest s)))))
So does this work?
=> (power-limit has-fixpoint 0)
ArityException Wrong number of args (3) passed to: core/keep clojure.lang.AFn.throwArity (AFn.java:429)

Doh! It turns out that keep only has a single arity and does not accept multiple collections like map does. So I'm stuck doing a (drop-while not ...) or (filter identity ...) or (remove nil? ...) to wrap the map operation.

The fact that I can remove all the leading nils, or all the nils (since all the nils are at the head here), made me take a step back again to think about what I'm doing. Once all the nils are out of the picture, I'm just looking for the first item in the resulting list. That's when I remembered some which tests all the items in a list according to its predicate, returning truthy/falsey, but the way it does this is to just return the first non-falsey value its predicate gives. So I still need to wrap the map operation, but I can drop the call to first.
(defn power-limit [f a]
  (let [s (iterate f a)]
    (some identity (map #(#{%1} %2) s (rest s)))))
Not as pretty as the very first implementation (which used loop/recur) but now it's not so verbose, so I'm feeling happier about it.

February 18, 2015 04:45 AM

Paul GearonLife in Clojure

A few months ago I was looking at the Life in APL video on YouTube and it occurred to me that other than the use of mathematical symbols for functions, the approach was entirely functional. This made me wonder if it would be easier (and perhaps clearer) to do it in Clojure. My goal was to show that Clojure was just as capable, and hopefully easier than APL.

I created Life in Clojure to do this, and it worked out pretty well. What I need to do now is to record a REPL session for YouTube, just like the original. However, there are a couple of things that were shown in the APL video that are missing in Clojure, and I needed to fill in the gaps. It's these gaps that I've been thinking about ever since, wondering if I could/should do better.

Since I don't have a video, Life in Clojure is implemented in a namespace that contains a REPL session. Just use "lein repl" and paste in that namespace file and it'll do everything in the same order as the APL video, with a couple of deviations. I've commented each operation with the appropriate dialog from the original APL video, so it should be easy to see the parallels. However, for anyone who wants to see it running, the final program is implemented in the life.core namespace.

Setup

The first change between these Clojure and APL implementations is that Clojure needs to explicitly import things into the environment, while the APL video seemed to demonstrate all operations being available by default. Given that most of these were matrix operations, and APL specializes in matrix operations, then it isn't surprising that these are built in. Fortunately, all the applicable operations are available to Clojure via core.matrix, so this was a simple require, along with a project dependency. I suppose I will need to show these at the start of any video I make (if I ever make it).

Output

The APL video showed the use of a display function that prints a matrix to the console. Clojure's pretty-print will also show an m*n matrix reasonably well, and I could have chosen to use that. However, the APL code is also printing a vector, and then a matrix, where each element is an m*n matrix, and pretty-print just messes that up.

The APL demo seemed to be using a library function to handle this printing, so it didn't feel like cheating to write my own. It's a bit clunky, as it's specialized to only handle 2, 3 or 4 dimensions, but it works.

The bigger issue was showing the current state of the Life playing field. APL was using a draw function to update the contents of a text file, and opened a window that dynamically showed the contents of that file as it was updated. Using a file proxy like this made the display easy in APL, but it's hack that I did not think was worth duplicating. Instead, I created a function to convert the playing field into an image, and sent the image to the display.

Creating an image from the matrix was an easy Swing-based function (just draw filled-in rectangles based on the contents of each matrix cell, and return the image). However, rendering it was a little harder.

Following the APL approach, I wanted a function that would "send" the image to the screen, and forget about it. However, Swing requires an event loop, and several listener objects to allow the window to interact with the environment. These sorts of objects do not fit cleanly into a purely function program, but using proxies and closures does a reasonably good job.

I was able to hide the default window parameters (width/height, etc), but had trouble with the fact that the APL program simply sends the output to the rendered file without defining it as a parameter. The main problem is that the open-window function should return the created resource (the window) and this value should be captured and "written to" each time the life algorithm needs to re-render the playing field. I could do that, but introducing this resource handling into the main algorithm would get in the way of the "clarity" that the demo was trying to express. In the end, I opted to create a global atom (called canvas) that gets updated with each call to draw. I would not usually write my code this way, but it seemed to be the best way to duplicate the APL demo.

Of course, not a lot of programs use Swing these days. The majority of programs I see with GUIs use a browser for the UI. So when a couple of my friends saw this app, they suggested reimplementing it in ClojureScript, and rendering in a web page. Funnily enough, the DOM ends up being an equivalent to the global canvas that I have in the Swing application, so the calling code would not need to change its approach. However, core.matrix does not yet support ClojureScript, so I haven't tried this yet.

Matrix Math/Logic Operations

One minor inconvenience in using the APL approach is that it uses the C-style idiom that the number 0 is the value for "false" and anything else is "true". The APL demo algorithm uses 1 to indicate that a cell is occupied, and then uses addition between cells to determine the values for subsequent generations. This creates an elegant shortcut for determining occupation for subsequent generations in Life, but it isn't as elegant in Clojure.

Of course, Clojure truthy values identify all numbers as "true", and only nil or boolean "False" have a falsey value. Without the zero=false equivalence, then the algorithm gets more awkward. Based on that, I created a function that takes a single argument boolean function and returns an new function that returns the same result mapping false->0 and true->1. This allows matrix addition to be used as the basis of the AND and OR operations, just like in the APL demo. It works fine, but I'm uncomfortable that it currently only handles the 2 argument case for the AND and OR matrix operations. Also, I've since learned a little more about core.matrix, and I think there may be better ways to define these functions. I'll have to look into that a little more.

There is also a convenience function I created which is used to map a matrix to boolean 1/0 based on each cell being equal to a given value. It's a simple one-liner that makes it easier to compare to the equivalent APL code but it always felt a little inelegant. However, this might just be due to the need to map booleans to numbers.

The other APL function that wasn't directly available to me was the "take" of a matrix. This operation allows a 2-D "slice" from a larger matrix, but also deals with the insertion of a small matrix into a larger "empty" matrix. After some examining of core.matrix I discovered that shape provided similar functionality, though it needs help from compute-matrix to handle expansions. I wrapped this in the function takeof to duplicate how the APL demo used it.

Powers and Power Limits

Up to this point, everything was either translating a library from APL (display, the graphics output, or some simple wrappers to smooth out matrix access, and handle the integer/boolean equivalence in APL). But right at the end of the video, the APL demonstration uses a couple of functions that had no equivalents in the Clojure. These are the power function and the power-limit function.

The behavior of the power function is to take a single argument function and apply it to an argument, take the result and apply the function to that, and keep repeating the application of the function as many time as requires. The specific operation of power is to return a function that applies the argument function iteratively like this for the defined number of times.

As an example, the 5th power of clojure.core/inc applied to 0 is:
=> (inc (inc (inc (inc (inc 0)))))
5
So (power-function inc 5) returns a function that applies inc 5 times:
=> ((power-function inc 5) 3)
8
The power-limit function is similar, in that it iteratively applies the provided function, however it does not stop iterating until it reaches a fixpoint value. That is, until the output of the function is equal to the input.

An example function that has a fixpoint is:
(defn has-fixpoint [x] (min (inc x) 3))
This returns either the increment or 3, whichever is smaller. If this is applied iteratively, then it will always reach a value of 3 and stay there.

My first approach to this naïvely executed the provided function n times:
(defn power [f n]  (case n
    0 identity
    1 f
    (fn [x]
      (loop [r x, i n]
        (if (zero? i)
          r
          (recur (f r) (dec i)))))))

This works, but one look at it was enough to tell me I'd gone down a blind alley. case statements always suggest that something is inelegant, and loop/recur often means that the Clojure's laziness and seq handling are being ignored, which implies that I may have missed an abstraction. Both are a code smell.

That's when I remembered clojure.core/iterate. This function applies a function iteratively, returning an infinite lazy sequence of these iterations. The required power is just the nth entry in that sequence, so the power function just becomes:
(defn power [f n] #(nth (iterate f %) n))
Much better.

Similarly, I'd implemented the power-limit function using a loop until the input equalled the output:
(defn power-limit [f a]
  (loop [a a]
    (let [r (f a)]
      (if (= r a)
        r
        (recur r)))))

Unlike the original version of the power function, I like this approach, since it clearly does exactly what it is defined to do (apply the function, compare input to output, and either return the output or do it again).

I already mentioned that loop/recur often suggests that I've missed an abstraction. This, along with neglecting to use the iterate function for power, had me wondering if there was a more idiomatic approach here. That's when I realized that I could pair up the iterated sequence of the function with its successor, and compare them. The result is:
(defn power-limit [f a]
  (let [s (iterate f a)]
    (ffirst
      (drop-while (partial apply not=)
                  (map vector s (rest s))))))
The iteration sequence is captured in the let block so that it can be re-used when pairing the sequences in the map operation. The vector is being used here to capture each iteration with its successor in vectors of pairs. Because iterate is lazy, the sequence of iterations is only calculated as needed, and only calculated once.

The drop-while drops off all pairs of values where the values are not equal. The not= operation can take multiple arguments, so rather than pull each of the two values out, I'm using partial/apply to provide the pair as all the arguments. The result of the drop-while/map is a sequence of pairs of argument/results (which are all equal). The final result is to take the first value from the first pair, hence the use of ffirst.

Conceptually, I like it more, and I think that it fits into Clojure better. However, it's less clear to read then the loop/recur solution. So I'm torn as to which one I like more.

February 18, 2015 04:03 AM

February 17, 2015

Clinton RoyMonday 16th February

Bus to work, after discovering that I had no spare clothes at work, somehow. That won’t be a problem for a couple of weeks now.

Horrible nights sleep meant I had to skip the new software engineering meetup.


Filed under: diary

February 17, 2015 06:56 AM

February 15, 2015

Clinton RoySunday 15th February

Felt rather ill after Humbug, I’m assuming it was the sushi place at Sunnybank yesterday.

Catching up on these here diary notes..


Filed under: diary

February 15, 2015 03:58 AM

Clinton RoySaturday 14th February

My first CoderDojo down at Sunnybank Hills.

I find the connection between shopping centres and libraries rather confusing, for former are loud, commercial and horrible places, very different to the latter.

I think the CoderDojo group went well, with some obvious room for improvement. Don’t try to lecture kids, give them a small, simple instruction and get them doing stuff immediately. One slide, one thing to try. If a kid has interest in a subject, don’t try to teach them something else, and that goes for both parents and teachers.

Have been asked to help with a Python course in the next few weeks..

Humbug later that night, some discussion with Russell around the sponsor prospectus.


Filed under: diary

February 15, 2015 03:56 AM

Clinton RoyFriday 13th February

Early morning walk to work.

A little bit of anatomy work later at The Edge.


Filed under: diary

February 15, 2015 03:51 AM

Clinton RoyThursday 12th February

Early morning walk to work.

Catch up meeting at The Edge, broached the subject of running the PyCon Australia workshops here again.

3D printing induction, which went quite well, except for running out of time. Tinker cad is quite a fun easy tool to get into. I attempted to design a key holder that my key could slide into, it ended up being too short, but the sliding mechanism was perfect.


Filed under: diary

February 15, 2015 03:49 AM

Clinton RoyWednesday 11th February

Worky work. There’s a building site across the road from work, and the three jackhammers are *really* starting to get to me. It used to be the case that I could kind of ignore them until later in the day, and only then would they get on my nerves. Now, ten minutes after I get in and I’m grumpy.

A Humbug member organised an OpenBSD hackathon at UQ this week, and tonight they held a few talks about what they’d been working on. Some of it was interesting, just to get an insight of where BSD is. A lot of it was just complaining about other Open Source projects and standards committees not doing things in the correct way. They are trying to do something things to improve the situation, but I still feel like they’re being arrogant about much of it.


Filed under: diary

February 15, 2015 03:45 AM

Clinton RoyTuesday 10th February

Waking up in Brisbane again.

After work I organised a bowling night for my birthday. It ended up working out quite well I think, except that the dj outside the venue and the constant music inside bore down on me.


Filed under: diary

February 15, 2015 03:34 AM

Clinton RoyMonday 9th February

A very early start for the flight back to Brisbane.

Collapse into bed basically as soon as I get home.


Filed under: diary

February 15, 2015 03:20 AM

Clinton RoySunday 8th February

Melbourne!

Went to a few of the exhibits that had caught my eye when looking for things to do in Melbourne.

The Walkley photography in journalism exhibit at the State Library of Victoria was a small set of high quality, moving photos.

Spent a large chunk of the day at the National Gallery of Victoria, practically everyone else was there to see some Paul Gaultier fashion thing, while I was there to see Alex Prager who does elaborate photography and film work. I was a little surprised that every exhibit, bar Gaultier, was free, so went through pretty much everything there, history, design, jewellery, art, modern.

A nice long dinner with F followed by a cup of tea at her place with M.


Filed under: diary

February 15, 2015 03:16 AM

Clinton RoySaturday 7th Februrary

Melbourne!

Catch up and breakfast with F. Straight after went for a walk with F&M to do a little shopping..and to make sure I got on the right tram for my next appointment.

Coffee and tea and lunch with M followed by a park wedding critique.

Killing some time in a gift store, found a world map covered in scratchy material that you scratch off once you’ve travelled to a place, bought for a Brisbane friend who travels a lot.

Dinner with D&P, then laps of Melbourne looking for a parking spot to grab gelato. Way too many people for me to be comfortable down there.


Filed under: diary

February 15, 2015 03:04 AM

Clinton RoyFriday 6th February

Bringing more stuff into work for this evenings Melbourne flight.

Flew to Melbourne, it was kind of hot! I tried to use the several phone apps to figure out the trams, but despite google maps knowing I was in Melbourne, all the apps still thought I was in Brisbane. With help from a local friend got the tram to the hotel.


Filed under: diary

February 15, 2015 03:00 AM

Clinton RoyThu 5th February

Bringing more stuff into work for the Melbourne trip, bus is easier than walking with all that.

Walked home from work.


Filed under: diary

February 15, 2015 02:56 AM

Clinton RoyWed 4th February

Bringing stuff to work for the Melbourne trip.


Filed under: diary

February 15, 2015 02:52 AM

Clinton RoyTuesday 3rd Febrary.

Walked to work.

Lunch with a friend at her workplace, bumped into another friend who just started working there :)


Filed under: diary

February 15, 2015 02:50 AM


Last updated: July 04, 2015 08:15 AM. Contact Humbug Admin with problems.