Wednesday, May 18, 2011 10:28:31 AM
The media headlines are full of unqualified statistics, some - but not all - are qualified within the article body. They're designed to shock without giving true substance, and are impossible to use in meaningful comparison, but are perfect fuel for rhetoric (and selling the concept of government policy it seems).
For those of you out there who haven't encountered this before, a qualified argument requires all of the base values required to perform a true comparison (one that doesn't require assumptions). "I spend £100 a year on chips" is unqualified. "I spend 1% of my wages on chips" is unqualified. "I spend £100 of my £10,000 annual wage on chips" is qualified, and can be used for substantive comparison.
I've recently had a lot of unqualified statistics thrown at me as a reason for choosing a course of action, and I suggested to the people that they should go back and rethink their argument. They got very angry at this, stating that the research was sound. The research may have been sound, but I was questioning their presented statistics, not their research ... and such hostility ... sufficed to say they won't be getting my business.
Sunday, December 28, 2008 8:24:14 PM
One of my more recent projects involves SNMP monitoring of services. Nothing new you may say ... well, we're talking about a PHP based webservice. PHP includes some SNMP interaction functions, but nothing for sending Traps, so an hour or two of tinkering, packet analysis and educated guesswork later, we end up with ...
Requirements
- PHP >= 5.2.0
- PHP Socket Support
class snmp_Trap
{
/**
* The 'group' to which the message is relevant
*
* @var string
*/
public $community = 'public';
/**
* The SNMP message type (6 for custom)
*
* @var int
*/
public $genericType = 6;
/**
* The SNMP message sub-type (for custom, this is application specific)
*
* @var int
*/
public $specificType = 1;
/**
* A message to go along with this Trap
*
* @var string
*/
public $message;
/**
* An Object Identifier for this Trap
*
* @var string
*/
public $oid = '.1.3.1';
/**
* How long the service this Trap relates to has been operational (in seconds)
*
* @var int
*/
public $uptime;
/**
* The IP address from which this request should be said to originate
*
* @var string
*/
public $ip;
/**
* Uses the SNMP core to send this message
*
*/
public function send()
{
snmp_Core::sendTrap($this);
}
public function __construct()
{
$this->ip = $_SERVER['SERVER_ADDR'];
}
}
# ----
class snmp_Container
{
public $type = 48;
public $children = array();
private $length_cache;
public function getLength()
{
return $this->getChildLength() + strlen($this->getLengthData()) + 1;
}
private function getLengthData()
{
if( $this->length_cache )
return $this->length_cache;
return $this->length_cache = snmp_Core::getIntegerHigh($this->getChildLength());
}
private function getChildLength()
{
$length = 0;
foreach( $this->children as $child )
$length += $child->getLength();
return $length;
}
private function getChildData()
{
$data = '';
foreach( $this->children as $child )
$data .= $child->getData();
return $data;
}
public function getData()
{
return pack('c', $this->type) . $this->getLengthData() . $this->getChildData();
}
# ----
/**
* Adds a container, and returns it for modification
*
* @param int $type
* @return snmp_Container
*/
public function addContainer( $type = 48 )
{
$container = new snmp_Container();
$container->type = $type;
$this->children[] = $container;
return $container;
}
public function addTime( $seconds )
{
$majorUnits = min((int)($seconds / 167772.1647), 255);
$majorUnitRemainder = $seconds % 167772.1647;
$mediumUnits = min((int)($majorUnitRemainder / 655.3647), 255);
$mediumUnitRemainder = $majorUnitRemainder % 655.3647;
$minorUnits = min((int)($mediumUnitRemainder / 2.5647), 255);
$data = new snmp_Data();
$data->type = 0x42;
$data->data = pack('cccc', $majorUnits, $mediumUnits, $minorUnits, 0x83);
$this->children[] = $data;
}
public function addOid( $version )
{
$versions = explode('.', $version);
// -- Unset the first one if empty (OIDs usually start with a period)
if( $versions[0] == '' )
unset($versions[0]);
$majorVersion = (int)array_shift($versions);
$minorVersion = (int)array_shift($versions);
$data = new snmp_Data(6);
$data->data = pack('c', min((40 * $majorVersion) + $minorVersion, 255));
$versionsCount = count($versions);
$versionsKeys = array_keys($versions);
for( $i = 0; $i < $versionsCount; $i++ )
$data->data .= snmp_Core::getIntegerLow($versions[$versionsKeys[$i]]);
$this->children[] = $data;
}
public function addString( $string )
{
$data = new snmp_Data(4);
$data->data = pack('H*', bin2hex($string));
$this->children[] = $data;
}
public function addInteger( $int )
{
$data = new snmp_Data(2);
$data->data = snmp_Core::getIntegerHigh($int);
$this->children[] = $data;
}
public function addIpAddress( $ip )
{
$segments = explode('.', $ip);
$data = new snmp_Data(64);
$data->data = pack('cccc', (int)$segments[0], (int)$segments[1], (int)$segments[2], (int)$segments[3]);
$this->children[] = $data;
}
}
class snmp_Data
{
public $type;
public $data = '';
private $data_cache;
private $length_cache;
public function __construct( $type )
{
$this->type = $type;
}
public function getLength()
{
return $this->getDataLength() + strlen($this->getLengthData()) + 1;
}
private function getDataLength()
{
return strlen($this->data);
}
private function getLengthData()
{
if( $this->length_cache )
return $this->length_cache;
return $this->length_cache = snmp_Core::getIntegerHigh($this->getDataLength());
}
public function getData()
{
if( $this->data_cache )
return $this->data_cache;
return $this->data_cache = pack('c', $this->type) . $this->getLengthData() . $this->data;
}
}
# ----
class snmp_Core
{
public static function sendTrap( snmp_Trap $Trap )
{
$request = new snmp_Container();
$container = $request->addContainer();
$container->addInteger(0);
$container->addString($Trap->community);
$mainContainer = $container->addContainer(0xA4);
$mainContainer->addOid($Trap->oid);
$mainContainer->addIpAddress($Trap->ip);
$mainContainer->addInteger($Trap->genericType);
$mainContainer->addInteger($Trap->specificType);
$mainContainer->addTime($Trap->uptime);
$extraContainer = $mainContainer->addContainer();
/**
* Special case - attached message
*/
if( $Trap->message )
{
$messageContainer = $extraContainer->addContainer();
$messageContainer->addOid($Trap->oid);
$messageContainer->addString($Trap->message);
}
// -- Prepare the data
$broadcastString = $container->getData();
// -- Transmit the data
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_set_option($sock, SOL_SOCKET, SO_BROADCAST, 1);
socket_sendto($sock, $broadcastString, strlen($broadcastString), 0, '255.255.255.255', 162); // -- SNMP port
}
public static function getIntegerHigh( $value )
{
if( $value >= 256 )
return pack('ccc', floor($value / 256) + 128, floor($value / 256), (int)$value % 256);
elseif( $value >= 128 )
return pack('cc', floor($value / 128) + 128, $value);
else
return pack('c', $value);
}
public static function getIntegerLow( $value )
{
if( $value >= 128 )
return pack('cc', floor($value / 128) + 128, $value % 128);
else
return pack('c', $value);
}
}
$trap = new snmp_Trap();
$trap->message = "This is a test of a character size restriction which seems to be placed on large messages. There must be a way around it, I hope anyway ... time will tell ...";
$trap->oid = ".1.3.4.7.2000.2.1";
$trap->ip = '192.168.2.20';
$trap->send();
Monday, August 4, 2008 7:55:01 PM
If you don't know what XKCD is, google it. You'll thank me later ...
Monday, June 30, 2008 2:46:12 AM
It's typical of life. I've been in full-time employment for 2 weeks now. The job is hard but rewarding. It's time consiming, challenging, fun, working with companies of note in the world today, but what's happened? Now that my time is at a premium, the level of requests for contract work I'm getting has jumped. I haven't generally told people I have less free time on my hands, they've just mysteriously, magically and in unison decided that now is the best time for me to do something for them. Murphey, how did you know?
So, here I am, at 4am(ish) on a Monday morning, after a solid weekend of work on one project, interrupted only by one trip to Cardiff to do some workesque stuff, and I have to be up and around in just under 4 hours to travel to England to perform my full-time duties.
As long as the invoices are settled in a reasonable amount of time, no complaints here ... yet, but I'm not going to be making a habbit of this. I repeat, I am NOT going to be making a habbit out of this. For anyone who was paying any attention, the second repetition was for my benefit. Take heed Jeff, I'm talking to you
Sunday, May 11, 2008 5:35:18 AM
I've been integrating external source into my code this morning, and found a mix of hard tabs (the tab key on your keyboard) and soft tabs (people using spaces to simulate the former). I began to wonder, is this a personal preference, or is there some difference a little less obvious which causes people to work with the old but reliable soft tabs? None of my sources are awake at this time of morning, so I took a few minutes out to do some research.
There are, as I can now see, loads of arguments on the net comparing the two, some offering technical comparisons, some doing little better than name-calling. The people who are practical about it seem to stand by my way of thinking, which is always a nice feeling.
I like hard tabs. I like indentation being a one key action for creation, navigation and removal, yet still very readable. I like being able to have this, yet each indentation taking only one byte. I like being able to take the source I'm given and via simple search and replace, reducing the size of each file by around 20KB. Of course, like anything, it's bad if used improperly, but for pure indentation, it is my 4-spaces-in-a-character god.
So, for the record, if you want me to like and respect you as a supplier of source code, use so-called 'hard' tabs. Of course, I'll respect your views if you choose otherwise, but only under one condition. You have a good reason for doing so
Some articles on the subject of Tabs vs Spaces
Friday, May 9, 2008 5:50:42 PM
For those who know my technological work, I'm an errorphobe. I don't like it when things throw errors, give warnings ... I like everything to think everything else is just dandy, and have my software get on. Zero reported errors makes for a happy Jeff.
So, when one of my IDEs throws a false positive error and I can't convince it to ignore said error, I get a bit miffed. PDT, the PHP Development Toolkit is a fine piece of software, built on the Eclipse foundation. It highlights errors and warnings in PHP and HTML with a nice level of accuracy and some fairly detailed descriptions, but it fails completely to support Smarty.
Smarty, for those not in the know, is an intermediary between PHP and HTML, kind of like a sub-scripting language to aid in presentation. It doesn't support complex logic, but has support for iteration, filtering, and a nice plugin system for handling repetitive display work. It also includes compilation support, and possibly the one thing I love about it most, it enforces code separation. Smarty doesn't interact directly with all of your PHP code, you have to define interfaces.
One of the GoogleCode projects a while back was SmartyPDT, a plugin for the PDT which supported smarty templating and such. This project was a fair attempt, had nice features, but didn't address the 'false positive' error problem. Even worse, it's now a dead project it seems, not having been updated for many months ... and finally, it doesn't work anymore. The latest versions of Eclipse, the PDT and the Java Runtime Environment seem to have thrown it a curveball, and the software just refuses to function unless you go retro.
So, all in all, I'm sitting here, working on one project in particular, and sifting through a list of 288 false positives which are all down to this silly little thing.
Todays debate, should I learn something about Eclipse plugins and try to fix this myself, or just live with it. Option #3, should I get a new IDE? Answers to these questions, and many more, at some undetermined point in linear time.
Wednesday, April 23, 2008 5:05:12 AM
For those of you who are techies at heart, I'm sure you know what MIMO, FIFO and their siblings are. For those that aren't, it's as follows.
- FIFO - File in, File out (like a queue)
- MIMO - Multiple input, multiple output
- WORO - Write once, read once
- WORM - Write once, read many
I've now started writing C# code for smart-devices. What does this mean? Windows mobile devices, things running Windows CE and Windows for Embedded Systems, all .NETtified to make the transition ultra sleek. The problem? The code looks damned ugly, and not through any immediate fault of mine. Sure, I could find ways of making it more readable, but compared to nicely streamlinable languages like PHP with loose types and associative arrays at your beck and call, I'm reduced to some nasty instances of multiple-type-casting to get the IDE to work properly, and all sorts of embedded function calls so I don't have to assign memory to a variable where it isn't needed.
Hence, my new standard, WONTRA. Write once, never try to read again. Once I get this code working, I think I'll happily forget it ever existed, and go back to blissful ignorance in languages that are a little easier on the eye
Thursday, March 20, 2008 3:56:29 PM
... next, the world.
After completing the hour and a half test, I was presented with a nice little message which told me I'd passed. Apparently, in this test, you're not told how well you did, and not given a grade, beyond pass or fail. While I was rather disappointed by the lack of feedback, it doesn't detract from the fact that I can now say I have a little piece of paper, signed by the company behind PHP, that says I'm reasonably good at answering multiple choice questions, hazzah!
Wednesday, March 19, 2008 2:01:36 PM
I'm watching television. Okay, I'm watching it while I work, but still, I'm watching television. Yes, I'm well aware it should be a mortal sin, but ... I was watching a show discussing all kinds of relationships, how they form, how they evolve. I was thinking about the ideal relationship in my head, and it didn't quite fit into any of the categories they presented, so I made my own.
Mutual dependency, mutual attraction, the stages of love, the stages of friendship ... nope, much simpler. Mutual and Creative Giving. A relationship with someone in which you are constantly thinking of them, constantly doing things or thinking of things to enhance their life, and they're doing the same for you. It doesn't fit into the paradigm they presented because it's materially selfless ... directly anyway, but for some reason it appeals to me.
If there are any theories on why that might be, postcards to ...
Wednesday, March 19, 2008 12:36:05 PM
The day has come, or more accurately, the day has been booked. Tomorrow, at 12:30, in the wonderful realm of Cardiff Bay, I am to fight for my right to become a Zend Certified Engineer. Despite how impressive it may sound, it's not a huge achievement on my lofty goals list, but it was an opportunity on special offer, and it's a piece of paper to quote. I'm starting to understand why these things count as marks of respect with some people.
Degrees, Masters, Doctorates ... then on the specialist side of things, you have Certified Engineers ... not quite as grand, but it's much easier, more focused, and experience led. I'll take every advantage I can get, especially for a hundred pounds.
A quick note to anyone who's looking to do any purchasing along these lines, live in the UK, buy from the states, pay no VAT or sales tax and benefit from the extreme currency value difference. Live in the UK, buy from Germany, pay 19% sales tax and lose from the strong euro. So if anyone asks, I live outside the EU, my closest retail centre was in the states, but I'm collecting in the UK ...
Bless.
1 2 3 4 5 ... 9 Next »