More of a self-note…
…since this has some project-specific things in it, but a series of fairly useful VIm-formatted regexes to convert PHP into Python/Django syntax.
:'<,'>s/$\([a-z_]\+\) = (isset($_\(GET\|POST\)\['[a-z_]\+’\]) ? $[^ ]\+ : false);/\1 = request.\2.get(’\1′, None)/g
:’<,’>s/$\([a-z_]\+\) = array();/\1 = []/g
:’<,’>s/$\([a-z_]\+\) = array($/\1 = {/g
:’<,’>s/is_numeric($\([a-z_]\+\))/\1.isdigit()/g
:’<,’>s/$\([a-z_]\+\)\[\] = \(.*\);/\1.append(\2)/g
:’<,’>s/$\([a-z_]\+\)\[\([\'0-9a-z_]\+\)\] = \(.*\);/\1[\2] = \3/g
:’<,’>s/\<true\>/True/g
:’<,’>s/\<false\>/False/g
:’<,’>s/strlen($\([a-z_]\+\))/len(\1)/g
:’<,’>s/\(}\? \?\(el\)\(se\)/> \?\)\?if (\(.*\))\( \?{\)\?/\2if \4:/g
:’<,’>s/ \?|| \?/ or /g
:’<,’>s/ \?&& \?/ and /g
:’<,’>s/::/./g
:’<,’>s/;$//
:’<,’>s/!\$\?\([a-z_]\+\)/not \1/g
:’<,’>s/\$\([a-z_]\+\)/\1/g
:’<,’>s/->/./g
:’<,’>s/^\t\+}\n//
:’<,’>s/} else {/else:/g
:’<,’>s/’\([a-zA-Z_]\+\)’ => \([a-z_]\+\)/’\L\1′: \2/g
:’<,’>s/\([a-z]\)\([A-Z][a-z]\)/\1_\l\2/g
:’<,’>s/ \. / + /g
:’<,’>s/_SESSION\['user'\].\([a-zA-Z_]\+\)/request.user.\L\1/g
:’<,’>s/\([a-z_]\+\)\['\([a-zA-Z_]\+\)’] = /\1['\L\2'] = /g
:’<,’>s/user.permissions.\([a-z_]\+\)/user.has_perm(’\1′)/g
:’<,’>s/Utilities/utilities/g
Writing code that makes an entire group of people cry is <3. ![]()
The Bloodclot and the Ambulance
I came very close to pushing someone down an escalator on the way home today.
Outside Baker Street Station is a controlled pedestrian crossing. Several other cold, wet, and tired commuters and I waited diligently for the lights to change and then crossed. As we reached the central island in the crossing, an ambulance arrived with its sirens and lights making a blinding racket behind the traffic stopped at the lights, so we stopped in spite of the green man flagging our safe translocation across the street. Cue Fat, Balding Idiot.
FBI ran up behind myself and the other CWTCs and shouted “Excuse me!” in his best impression of Norris from Coronation Street as a car slowly began to move against the lights so the ambulance could get past. Naturally, none of us moved, and FBI was stuck behind myself and a very pissed-off nurse. He then says this:
“Oh, you are all so slow!”
I span on my heels so fast my manbag whacked against the railings and the Swedish-looking blonde next to me eeped, and I broke the first rule of Britishness: I voiced my thoughts to a complete stranger in the street in full view of other strangers. In fact, my exact words were as follows:
“Slow?! What the HELL were you going to do, run out in front of an ambulance, you bloodclot?! Please, be my guest! With a little luck it’ll have reached 30 by the time it squashes your pathetic skull under its three-tonne body, and the person you prevented from receiving life-saving help would die in excrutiating pain whilst the paramedics instead spend their time on your pathetic waste of skin!”
Someone behind him cheered, and a couple of others clapped whilst FBI looked on in stunned silence. A moment later, he said, quietly:
“I only wanted to cross the road…”
I lifted my hands, and my finger automatically moved into that claw-like position that happens when someone’s brain issues the command to do right by society and perform the public service of throttling the life out of the low-grade inbred standing ready before them, but I growled with frustration and shouted “DIE IN A FIRE!” at him before flouncing across the road with the now green light.
I entered Baker Street station and bought a bag of dried cranberries from the little shop on the concourse (for I am Middle Class Scumbag) and went through the barriers and started walking down the escalators. On the second down set, I passed FBI, who was standing looking miserable on the right-hand side of the escalator. I honestly had to force myself not to stop walking and grab him by the collar and frog-march him down. It’s nice to know that London, like all cities of the world, has the sort of fat and selfish low-lives who are so busy that they are prepared to hold up an ambulance responding to an emergency call but are too lazy to walk down a 20-metre escalator.
Some days, a license to eviscerate and expunge would be a most welcome possession.
Lloyds ‘ClickSafe’
Honestly, this lot take the cake. There’s no way for them to stop their customers from getting requests to sign away their rights as a consumer except by making them sign up to their pitiful implementation of the farce known as ‘3D Secure’ and then removing it from the card.
Why are there no sensible people in system design any more?!
Oh, what I wouldn’t give for an unending supply of mind-bullets…
Today has not been a good day. My feet are wet because the sole of the right boot of my three-month-old 57€ boots has cracked. A man who smelt like Airfix glue sat next to me on the train and squashed me against the chassis of the carriage. When he finally got up and left the quiet coach, a dregs-of-the-bottom-of-the-pond pregnant got on with her spawn and her mother, who promptly sat down beside me and, after whacking me in the face with her elbow without apology, continued to encourage the little brat that had sat on her lap to bang his head against the seat in front.
The little brat in question kept asking the clueless matriarch what Santa was going to get him for Commercialmas, and I was so close to leaning in his face and yelling “SANTA’S DEAD YOU LITTLE INGRATE, NOW SHUT UP!!” it’s not even funny. As it was, coughing and tapping the Quiet Carriage sign stuck to the window offended my sensibilities enough without daring to speak to one of the Great Unwashed on one of our overheated Great British trains.
So, you can imagine my inexorable joy when, after fighting my way through the crowd of drones incapable of working out that they’d all get through just that bit faster if they got their tickets ready in advance, I arrived at my car to find a Penalty Charge Notice stuck to the ice on my window. The notice cites:
Contravention: Vehicle registration L34KYPU parked in a car park without clearly displaying a valid pay & display ticket or voucher or parking clock.
Cue funny looks from the aforementioned drones as they pass me swearing loudly at Cretinus Antisententia, the Invisible Flying Moron Traffic Warden Moron.
So, I’ve just fired off the following e-mail to them:
Hello,
I hope this finds you warm, as I’m currently freezing in my ice-covered car in the car park on Road Street in Villagetown, Surrey. Attached is a photo of my ice-covered car, to the ice-covered windscreen of which your traffic warden has stuck a now ice-covered Penalty Charge Notice. Also attached is a photo of my thin, ice-covered paper ticket for parking in the aforementioned car park, which cost no less than Five Whole Great British Pounds Sterling and was stuck to the inside of the ice-covered window… I’m sensing a theme, here.
If you check your CCTV cameras - you do have, CCTV cameras, don’t you? Because otherwise one wonders why the parking is £5 - you will quite clearly see me purchasing a ticket at 07.15 GMT this morning from the machine next to my car and putting it inside my car before slipping on the ice whilst trying to run for my train - which I missed - and landing squarely on my coxxyx. It hurt. Just so that it’s clearer for whom you are looking, I’m short, fat, have dark blonde hair, am wearing a suit, and was carrying a laptop bag. That ended up on my face. That hurt too.
So, I suggest that you implement a payment-by-phone option in this car park, as this will negate this sort of problem in the future. This way, your Wardens would be able to check in real time which vehicles were actually parked and paid-for and which ones are being driven by the inbred scum-of-the-Earth that cause your Wardens to physically exist. In fact, my company could even implement one for you! The business e-mail is info@company.com, and we’ll supply you with a quote for development and implementation upon receipt of a brief detailing your specific requirements.
Oh, and please cancel the ticket. Its reference number is KILL4LLPUPP13S. My address is 1 My Street, My Town, Surrey, BA5T 4RD, England, United Kingdom, Europe, Earth. I have been driving the leaky bucket of rust that is L34KYPU since 2007, when its plague-ridden existence came to my much-maligned life.
Oh, and lastly, I’ve attached a third photo of my car next to the ticket machine under the lamppost by the tree on the pavement of Road Street in Villagetown, Surrey, just in case it’s unclear which CCTV camera you need to check.
Finally, I wish you season’s greetings, because the Politically Correctists say that wishing people a merry Christmas is forcing your religion on somebody and thus a prosecutable criminal offence.
Regards,
Grump.
Does my willing for all Traffic Wardens, Parking Attendants, and Civil Enforcement Officers to spontaneously exploded into sheets of flame and drive away the cold weather with their carbonised exteriors show through?
Radians
No, I’m not talking about the alien-worshipping religion (which is the Raelians anyway); I’m referring to the world’s most pointless rotation / angle measurement.
Everyone on the planet knows about degrees: 360 degrees in a perfect circle; 90 degrees is a quarter; 120 degrees is a third, so on and so forth. Standard mathematical measurement for angles and rotation. You’d think everyone would use it.
No, Adobe, in their infinite wisdom, don’t. For some reason, they’ve decided that the Matrix class in ActionScript 3 should use radians to mark its rotation. Not degrees. It took me ages to work this out, as I was putting in 90 for the rotation I wanted and was getting 116 degrees (5156.62 degrees, actually, but neh).
I honestly have no idea why they would choose radians as the unit for this. Not only does it result in fractional numbers, it’s a nightmare to convert in and out of. Oh, but I forgot that it makes sooo much more sense to put in 1.57 as my rotation instead of 90. Stupid me.
*stabs idiot ActionScript 3 designers*
Apparently, I have two 1997 Seat Arosas
At least, this is what my insurance company seems to think, since they are charging me for two policies.
I’m currently on the phone to them, and I’ve been informed by the call centre minion that he can only check the details on one of the two policies as they have two completely separate systems. Riiiight… So, he’s currently trying to find out just what, exactly, is going on with the other policy.
Honestly, why can’t any company get it right? I am beginning to wonder if there is a little glitch fairy whose only job is to run around and poke holes in any files that relate to me.
The guy on the other end of the phone is telling me that they have two completely separate insurance systems. In October, I phoned up the company and was told by their agent that I couldn’t renew the existing policy because it had passed the end of the contract date, and that the car had been uninsured for a few weeks. Fortunately, it had sat on the driveway for that time, so no harm was done. I opened a new policy with them and thought nothing of it.
It seems that the original policy was not cancelled automatically and, in fact, just continued. More Than have opened the second insurance policy on my car because the left hand didn’t know what the right hand was doing. Having been told by the agent at the time that the existing policy was cancelled automatically, I amd somewhat unamused. Am I the only person who thinks that their system should have gone “Boing! This person is already insured!”?
Note: I originally wrote this in May, when I discovered the problem. My insurer had been charging me 2.5x what they should have been charging me, and it had taken me that long to twig that they had been doing so. Had it not been for the git in Fabruary cloning my card, I probably wouldn’t have gone over my bank account with a fine-toothed comb and noticed it. In the end, they refunded me the money - £362.94. Was nice to see my overdraft decrease somewhat, if only temporarily.
VAT and foreign websites
A lot of people reading this blog will be aware that the EU has a tax on non-essential items which, in the UK, is called Value-Added Tax, or VAT. The annoyance of VAT itself aside, it is a legal requirement for sites to support it when selling things for VAT-registered entities based in the EU. Now, usually this isn’t an issue, as sites selling things from the EU are usually built in the EU. Unfortunately, there’s this big site which is popular for some reason called eBay.
eBay doesn’t like VAT. When I say it doesn’t like it, I mean it doesn’t implement it properly. You see, eBay is a site which was launched in the U.S.A. and has since grown to other markets. This shows in the way it handles taxation.
For US listings, eBay has a really in-depth tax system in its API which allows you to specify tax levels on a per-state basis.
For EU listings, we have one field: VATPercent. This takes a floating-point number that tells the system to display a message on the listing that the list price contains VAT at the specified rate. This seems to be all it does.
When you buy an item with this VAT message on it from outside the EU, eBay still bills you the list price - it never deducts the VAT from the list price. Conversely, if you buy an item listed in the UK from the UK, the VAT is never added on, so that VATPercent field seems to only make eBay display the message that VAT is included in the list price.
Let’s not even begin to talk about getting support for this sort of problem, or even a clarification on how VAT works on eBay. I’ve been working on this auto-listing system for a month, and it still doesn’t work properly because every time I fix one issue, another one arises, and eBay’s developer support team will only answer the question you ask them, not volunteer answers to other problems which will appear in the future.
Honestly, I sometimes wonder how the entire system hasn’t collapsed under its own weight. The more I look at the API, the more I see a series of hackish attempts to attach some new functionality to previously-written hackish attempts to provide new functionality. They really need to break backwards-compatibility at some point and re-design it from scratch. Perhaps then we will actually be able to list things properly from outside that little conglomeration of nations at the top of the New World without having to fight the system at every step.
Now, don’t get me wrong; this isn’t something that just affects eBay, but it certainly is the most visible example of a site which must support VAT in order to do business in the EU and has implemented it in a way that is so bad as to almost be completely useless.
Bureaucracy
Today I found out that our delivery driver had been fined by his employer because of a rounding error on a dispatch label.
We sent out a 10g - yes, 10 gramme - item through their site, printed off all the correct labels, etc, and dispatched it in one of their small item envelopes - lets call it a SpeedExPak. The item reaches customs, and they go “Uh, the weight on this is 0.0 kg. We can’t take it. Sod off.”
So, this comes back to us, and it leaves me going “WTF” for about an hour whilst I try to work out where the rounding error has come from. Eventually, I track down the error. Which is at the delivery company’s end. In their label generation software. Which rounds to 1 decimal place.
So, they fined their driver because of a bug in their own software caused which they should have picked up before the labels were printed.
When I rule the world, I’m outlawing bureaucracy and shooting anyone that tries to get me to fill in a form because That’s How It’s Done(tm).
Flash! (Ah-ah!) ActionScript 3 varDump function
So, recently I’ve been doing a fair amount of work with ActionScript 3 in Flash, and its complete lack of a useful variable dumping function has really started to get on my nerves. So, after a lot of toing-and-froing, I eventually found some examples which partially did what I wanted them to do.
Most of the problem was that they didn’t give enough information, or they only dealt with a small sub-set of the code, so I built this function to give a decent dump of pretty much anything you can throw at it.
So, here’s my varDump function:
package grump.utils {
import flash.utils.getQualifiedClassName;
import flash.utils.describeType;
public function varDump(_obj, includeAccessors:Boolean = false, depth:Number = 0, key:String = ''):void {
var indent:String = '';
var i:Number = 0;
for (i = 0; i < depth; i++) {
indent += ' ';
}
if (_obj == null) {
if (key) {
trace(indent + key + ":null");
} else {
trace(indent + "null");
}
} else if (_obj == undefined) {
if (key) {
trace(indent + key + ":undefined");
} else {
trace(indent + "undefined");
}
} else {
switch (typeof(_obj)){
case "object":
if (key) {
trace(indent + key + ":" + getQualifiedClassName(_obj).replace('::', '.') + " {");
} else {
trace(indent + getQualifiedClassName(_obj).replace('::', '.') + " {");
}
var varList:XMLList;
if (includeAccessors) {
varList = describeType(_obj)..variable.@name + describeType(_obj)..accessor.@name;
} else {
varList = describeType(_obj)..variable.@name;
}
var varType:String = '';
for (i = 0; i < varList.length(); i++) {
try {
varDump(_obj[varList[i]], includeAccessors, depth + 1, varList[i]);
} catch (e:Error) {
if (e.errorID == 1077) {
trace(indent + ' ' + varList[i] + ':Unknown = write-only parameter');
} else {
trace(indent + ' ' + varList[i] + ':' + varType.charAt(0).toUpperCase() + varType.substr(1, varType.length) + ' = unknown - ' + e.message);
}
}
};
for (var item:Object in _obj){
varDump(_obj[item], includeAccessors, depth + 1, String(item));
try {
varDump(_obj[item], includeAccessors, depth + 1, String(item));
} catch (e:Error) {
if (e.errorID == 1077) {
trace(indent + ' ' + item + ':Unknown = write-only parameter');
} else {
trace(indent + ' ' + item + ':' + varType.charAt(0).toUpperCase() + varType.substr(1, varType.length) + ' = unknown - ' + e.message);
}
}
};
trace(indent + "}");
break;
case "xml":
if (key) {
trace(indent + key + ":XML {");
} else {
trace(indent + "XML {");
}
trace(indent + " " + _obj);
trace(indent + "}");
break;
case "string":
if (key) {
trace(indent + key + ":String(" + _obj.length + ') = "' + _obj + '"');
} else {
trace(indent + "String(" + _obj.length + ') = "' + _obj + '"');
}
break;
default:
var type:String = typeof(_obj);
if (key) {
trace(indent + key + ":" + type.charAt(0).toUpperCase() + type.substr(1, type.length) + " = " + _obj);
} else {
trace(indent + type.charAt(0).toUpperCase() + type.substr(1, type.length) + " = " + _obj);
}
break;
}
}
}
}
Yes, it’s ugly, full of redundant code, and there’s some arse-about-face logic in it, but it works, and it gives you enough information to properly debug stuff.
Stick that code in grump/utils/varDump.as in the same folder as your Flash source and add import grump.utils.varDump to the top of your package to load it.
Note: Using includeAccessors on some objects will result in an error when it tries to read a write-only parameter. Why Adobe decided to have write-only parameters, I have no idea, but they did, and I haven’t yet figured out how to ignore them, so if anyone knows how to do so, please let me know and I’ll update this code to reflect it.
Note: Still don’t get why they decided to add write-only parameters, but the bug mentioned above is now fixed.
Output dumped is very useful indeed.
Tickyboom thing
I just found the most bizarre code comment ever in one of the files on the site I’m currently working on.
/*Not sure what this does but if you comment it out the little tickyboom thing stops ticking and goes boom.*/
I honestly have absolutely no idea what that’s supposed to mean, or what it’s referring to. It’s isolated on its own in the middle of the file with about 10 lines of whitespace on either side.
Bizarre…
