Author: francis

How I write big things

For me the best tool is a mapping tool of some kind. I used to use Mind Manager, which is a good tool that does the job very well. I also liked the export to HTML and M$ Word. The corporate edition does things like allow you to have brainstorming meetings and so on. I like it but don’t need it. If  you work for a big corp and have to do a lot of collaborative design stuff I recommend it though.

If you want to put a lot of information on a node it goes into a note field at the bottom, which is OK

I then played with the brain for a while but the export tools are not good enough. You can get a tool from the website that will allow you to export the brains you generate to XML – this is where the fun starts because it doesn’t take the notes with it, these are held in separate RTF documents. In essence, if you are using it to plan a written document, it isn’t good enough. It’s good for organising thoughts and so on but just not that good to put up with the very poor export facilities.

I have finally started to use free mind, which is essentially an open-source clone of Mind Manager with better facilities. It also has this really useful multi-line node thing that means you can put a lot of text into a node, then press F6 to shrink the font. I’ve been using it a lot to plan my work at work as well. Free mind is a bit pure in that it won’t export to proprietry things like M$ Word but so what? I use Open Office for personal stuff anyway. Free mind has almost all of the same key strokes as Mind Manager, except that alt-enter puts you in multine node mode. It also supports notes on nodes but you have to dig for it on the menus. I like the mode where you can look at the nodes as a simple hieriachy and select many at a time, as well as the way it does links between nodes.

Another good thing about free mind is that it’s open source and, erm, free. You do need to have a Java Runtime installed though, but so what? You need one anyway for your web browser.

In an ideal world I’d like something like the brain with decent export facilities, the radiant thinking thing of mind maps is good but I like the way you can hoist another node into the centre of the visual field with the brain, just the export facilities are crap (who but a techie could even deal with XML, or even want to, for goodness’ sake!) and freemind does the job well enough for me. Mind maps work well for project planning and work management as well, they allow you to jump about and look at priorities, which is something I’ve been forced to do a lot of recently. Mind maps let you see the big picture and the brain doesn’t – it’s all horses for courses really. Actually, in an ideal world I’d like to be able to have a mind map with hook points where I can hoist a node up to be the centre of another map (and keep everything in sync) – the best of both worlds. Hmmm… Free mind is open source …. hmmm … maybe I could do some experimenting with it?

Maybe when I get some time…

[[ Note added 16-Apr-06 ]]

Not overwhelmed by Free Mind when I try and print a mind map. It looks fine on the screen but on my ink jet printer not so good, the text seems to be doubled up and higgledy piggledy. This may be something to do with the Java library’s printing facilities and not something that the free mind developers can control. I will ask them about it on the site.

It’s official: The Pressure Cooker has exploded

Last blog entry I said I was really under the weather and struggling.

I went to see my doctor and told her that my IBS was playing up, I hadn’t slept properly in weeks and my sinus condition was playing up. My eyes also look like they belong to someone else as in they’re so sunk in you can’t see them properly.

She takes one look at me, looks at my medical history, and signs me off for two weeks

“Let them go hang”

That’s what she said.

I feel bad though – we’re in the middle of a big release. However the work I did that was on the main track has largely been done and the guy who seems to think I can be his hands driving Oracle Designer can just remember how to use it himself; it’ll be good for him to make the odd decision I think.

However, I can’t even work from home because I’d be uninsured. Once the doctor has said you aren’t fit for work then you can’t go in.

I am very tired. I have slept an awful lot, I didn’t realise how wrecked I was. Also having trouble driving, being very careful and taking my time – can’t do that instant evaluation thing I usually can.

Oddly I fired up my work laptop so I could re-initialise my Palm Tungsten (let the battery go flat) and even looking at the thing made my head hurt.

I think the main problem is a complete lack of autonomy – priorities being changed all the time and no part in the decision making process. That combined with being managed by someone who isn’t very good at people (see earlier couple of blogs). Anyway, I’m resting and trying to get my strength back. Also doing some exercise because my doctor advised this to get rid of the fatigue poisons that have been building up for so long. Did a session on my cross-trainer this morning and couldn’t get to 20 minutes. Legs are aching all the time too. Suspect I just need to rest up …

Sigh.

The prize goes to the guy who fills in the forms?

Well, this is difficult for me. I did a lot of voluntary work for my local canone club. Not for gain, just because I enjoyed it and wanted to give something back to the many coaches who had helped me become proficient at the sport.

We also had a lot of good young people at the club and they needed to stretch on white water and outside of the boring narrow confines of the pool and the lake.

I stopped going to the pool because I didn’t agree with the way the sessions were being run by the Capsize Stazi who were forcing scared kids to capsize their kayaks and do a capsize drill. My daughter was one of the victims, but not the only one. When I coach I never force anybody to do anything, all I say is if you want qualification x you must meet the criteria. If you don’t want it today, that’s fine, no worries. My daughter won’t even get in a kayak now. Not that I’m angry about this or anything, honest. Not much.

OK, I ran one event a month for the best part of 2 years. Rosie ran one also, she prefers flatter water and social paddling. Hey, this is good, if she wanted to do white water we’d always be fighting over child care.

About 9 months ago I realised that I had “coachitis”, as in my own skills were not progressing, going backwards if anything, and I seemed to be spending all of my time helping others and getting frustrated. I decided to take some time off but, because I am so fed up, I haven’t been kayaking for myself, I haven’t done any at all. This is upsetting because I used to get so much pleasure out of it. I’ve tried to go out a number of times and it always feels like my limbs are made of lead and I go climbing or walking instead. Note that I got no support from the club at all – no-one even bothered to talk to me.

In the midst of all this the club’s ineffectual chariman (nice guy, always says he’s going to do things and never does) decides (or gets talked into, I think) that we should go for “top club” status. This means we can apply for grants and things (we already have more kit than we can use because of earlier success). I don’t care about such things, think they’re nonsense to be honest. In fact I think its state-sponsored bureaucratic crap that allows politicians to say they’re helping the community because they put 50 pence in a tin. I’d rather be self-sufficient and pursue my sport for its own sake. I also have talked to other paddlers in other parts of the country who have no kit at all and need grants and so on a hell of a lot more than we do.

After a lot of humming and ha’ing and help from the club secretary who actually does the work of filling the forms in, proving we do enough to justify this status, and it is granted. I think I made a substantial contribution to this, as did Rosie, and have been thanked at most once. Thing is, there’s been almost no extra-curricular activities since I withdrew. I’m not sure that the status is deserved any more.

The other active coach is a very self-centred guy who is responsible for the Capsize Stazi incidents. He is apparently doing the 3 things he always does (when he doesn’t cancel with a week’s notice). He only ever does things if they are of personal benefit to him and is always finding ways of not spending his money. It’s a very unedifying spectacle and gives me the creeps. There was an incident when I was paddling with him when I thought I was going to die, but that’s another story. I decided not to paddle with him because I don’t trust his judgement, this was before the incident with my daughter and I wish I had spoken up then, but if wishes were fishes … I suppose I should learn from it and speak up next time and every time.

The chair has decided to have a big jamboree on a weekend Rosie and I can’t make it. All of the local politiciains will be there and the press, glad handing him and others. This will not do his career, or the that of other coach, any harm at all. They are or will be teachers or youth worker co-ordinators. To be fair, I don’t think this was deliberate, just typical of the cloth-eared way he does everything. We were given two ears and one mouth and should use them in that proportion, which he does when it suits his plans, which I suppose means he doesn’t listen really.

Then there is the vexed question of the website. My dear friend Roger set it up for us for free on one of his servers, it has content management and all sorts of useful stuff like diary management and bulletin boards if we can find time to learn to use it. The chair thinks it doesn’t work and keeps getting people who are not IT professionals, which Rosie and I are, to do things for 50p. If the club were buying equipment then we would ask the people who know for their opinions, but because your mate can do a web site for £50 and you haven’t bothered to ask (or even read the minutes of the meetings when you were told) you don’t realise you alreay have a site that will meet all of your needs for nothing. Cloth ears and wasting club funds. But just stupid and ignorant. To be honest you get this all the time with the web, everyone thinks they can do it for a packet of crisps and wonder why it looks crap when they do. It’s also a control-freak thing – getting his mate to do it puts him in charge.

Rosie resigned from the committee a couple of days ago from sheer frustration at nothing ever getting done. She used to play buzzword bingo:

“keep on agenda” – no-one’s bothered to do anything (again)
“the chair will do that” – it won’t happen
“coaching report” – my PC broke (I couldn’t be arsed)

Plus the words “the pool” and “the lake” and “top club” will be mentioned. This will also take all night. The comittee members promised newsletter articles every month and there never are any. Rosie was suppose to put them up on the web site but you can’t put stuff up that’s not there, can you? This may be why the web site is thought to be bad, I dunno.

Please understand, I’m not angry. I did the voluntary work because I wanted to and would have done it anyway. I just feel that it’s been manipulated into something that I wasn’t ever consulted about and may not agree with. I just don’t know what it is and no-one’s ever thought to tell me.

I haven’t renewed my membership this year and I will definitely get back into a kayak. I have joined a different club who (wait for it) JUST GO PADDLING FOR FUN!!!!!! Whoeee !!!!! All I need to do is overcome my unwillingness to get in a kayak because of all the bad connotations it’s been generating in my mind.

Change management?

Just reading this while I eat my lunch:

Very interesting thought in amongst the excellent material:

A late change is a competetive advantage.

That’s well worth remembering, as long as you are using a method or practice that makes changes cheap and relatively easy to do.

Also

… predictable processes require components that behave in a predictable way. However people are not predictable components.

I agree so much. I believe very firmly that 90% of software development is people. The technology and the “methods” are at best 10%.

Some non-obvious things to do with PL/SQL tables

1. Test a lookup

PL/SQL tables can be indexed by varchars as well as simple integers, so,


type id_lookup is table of integer index by emp.name%type ;
emp_lookup id_lookup ;

— create a cache in a global package variable somewhere
for e in (select emp_id, name from emp)
loop
  emp_lookup(e.name) := e.emp_id
end loop ;

— Later define functions
function emp_exists( ename in emp.name%type )  return boolean is
begin
   return emp_lookup.exists(ename) ;
end emp_exists ;
function get_emp_id( ename in emp.name%type )  return integer is
begin
    if emp_exists(ename)
   then
      return emp_lookup(ename);
  else
    return null ;
  end if ;
end get_emp_id ;

Of course, you’ll have to do things like maybe force the ename to be upper case or some such to make it work properly but I didn’t want to clutter this up.

2. (more to follow)

US Social Security Numbers – a basis for fraud?

In reply to this article:

I think a lot of UK/European readers won’t get why the social security number thing is such a big deal. If memory serves some genius back in the early days of US IT decided that, rather than give everybody their own customer number, they’d just use the guaranteed unique SS number. This soon became common practice.

So, it’s not that McNealy’s SS number is compromised particularly, more that a knowedgeable hacker can use this number when they break into other systems to find out things about him and also pretend to be him and commit fraud.

In the UK I don’t think most of us would give a toss if someone knew our NI number because it isn’t plastered all over our credit card vendor’s internal systems. I do wonder if this will change if the UK government manage to get their crackpot id card scheme off the ground, will this number then start mattering because it will be plastered everywhere like it is in the US? Then the hackers will find committing fraud (sorry, “identity theft”) much easier. I bet no-one’s thought about it at all.

Regards,

Francis Fish

Fun with XPath: Combining many fields in a query.

This is one of those things that are so obvious I felt like kicking myself when I realised how to do it.

First, some XML:

<?xml version="1.0" standalone="yes"?> 
<styling_rules >
<rule column="NAME" >
<features style="MAG:C.WASSNAME.CHOCOLATE"> NAME=‘T BAR BOO’ </features>
<label column="NAME" style="MAG:T.STREET NAME">1</label>
</rule>
<rule column="NAME" >
<features style="MAG:C.WASSNAME.CORAL"> NAME=‘UP A CREEK’ </features>
<label column="NAME" style="MAG:T.STREET NAME">1</label>
</rule>
<rule column="NAME" >
<features style="MAG:C.WASSNAME.CORNFLOWERBLUE"> NAME=‘UNHAPPY VALLEY’ </features>
<label column="NAME" style="MAG:T.STREET NAME">1</label>
</rule>
</styling_rules>

This has been anonomised for the purposes of this discussion. The tool that uses the data flattens the two elements inside the rule element out so fine. I needed an XPath that would get me a particular rule node so I can manipulate it.

I put my SQL head on and looked for two sets that I could combine:

xPath = "/styling_rules/rule[column='NAME']/features[style=‘MAG:C.WASSNAME.CORNFLOWERBLUE’ ” + 
” and /styling_rules/rule[column='NAME']/features/[text() = &quot; NAME='UNHAPPY VALLEY' &quot; &quot; ;</pre><br />Nah, don't even go there, it doesn't choke but it doesn't do anything. Instead think directory path and the *nix <em>find </em>command comined together:<br /><pre>xPath = &quot;/styling_rules/rule[column=‘NAME’]/features[@style=‘MAG:C.WASSNAME.CORNFLOWERBLUE’ ” +
” and ./text() = " NAME=‘UNHAPPY VALLEY’ " ]/parent::” ;

This should get me the whole node and I can then update the elements in it to my heart’s content.

Java: finding nodes with xPath and how to Dump out XML DOM as a string

After some google hacking (and reading Building Oracle XML Applications, which I thought was way out of date, my first edition of Java and XML was useless) I found this kind of stuff:

XPath

To use XPath you need an XMLDocument object:

  DOMParser p = new DOMParser();
p.parse(new StringReader(xml));
  Document doc = p.getDocument();
  XMLDocument xmldoc = (XMLDocument)doc ;
  NodeList nl = xmldoc.selectNodes(xPath) ;

Now we have a loverly list of nodes, and off we go.  Note that this suffers from the usual Java nonsense of returning a null if there’s nothing there.

Getting a String version of a DOM Document

toString()

Hmmm – just gives the object ID. How useful is that? Not very.

I noticed that the XMLDocument class has a print method that you can pass an OutputStream to. OK, I think, pass it a StringWriter?

        StringWriter sw = new StringWriter() ;
        xmldoc.print(sw);
        System.out.println(sw.toString());

This compilies but throws a Null Pointer Exception. Must be the interfaces matching but not doing what they’re supposed to. I dig around in the class documentation and find that I can pass a PrintWriter – this works:

    StringWriter sw = new StringWriter() ;
PrintWriter pw = new PrintWriter(sw );
xmldoc.print(pw);
System.out.println(sw.toString());

No idea why, haven’t got time to mess around finding out. It works. I think this is superior to a solution I saw where people were calling the serialize method on some weird class or writing your own code that dumps out the contents of a node and passing the root node to it (there are lots of examples on the Web if you look around). Note that this doesn’t work with fragments, at least it doesn’t seem to, have a play with it.

Coming up Fun with XPath: Combining many fields in a query. (when you aren’t trying to write some XSL).

Forwarding mail from a webmail account using python

NOTE: The code here is provided for discussion purposes, if you choose to use it yourself on your own head be it! I used Python 2.4 with emacs and the python.el mode file.

POP mail from my Macmail account hasn’t worked since December. I’ve emailed the support people a few times to no avail. It’s a free service and I don’t think anyone’s home any more. I decided to try and write a program that would pretend to be a browser and just forward everything on to my gmail account.

This was surprisingly easy.

I decided to use Python, because I know it a bit. CLisp was my second choice but there don’t seem to be the wealth of examples on the ‘net. I’ve done stuff like this in Java, but you have to do crazy things like run it through jtidy first and treat the html as xml, which is a complete pain. The Python SGMLlib just works.

I read the HTML processing chapter of dive into python, which gave me a grounding for the what I needed to do with SGML processors and stuff.

But first, I needed to learn how to log onto the mail service using cookies. I found this on the ClientCookie module, and that did the trick.

I then made a big messy file that I could run in emacs and keep stuffing prototype code into the Python interpreter. After some work I came up with this for the logon:

macMailURL = "http://mail.macmail.com"

def login2Macmail():
    request = ClientCookie.Request(macMailURL)
    # note we’re using the urlopen from ClientCookie, not urllib2
    response = ClientCookie.urlopen(request)
    firstPage = response.read();
    #print firstPage
    # Now we need the sessionID
    data = "login=aname&name=aname&pwd=apass&password=apass"
    # let’s say this next request requires a cookie that was set in response
    request2 = ClientCookie.Request(macMailURL + "/logon.php?logoff=1")
    response2 = ClientCookie.urlopen(request2,data)
    return response2.read()

This returns the inbox html from the second response. I’ve left the commented debug statement in.

So, now we need to take this page, rip out the <a> tags that point to emails, and use this info to forward the mails:

class collectTags(SGMLParser):<br /><br />&nbsp; def reset(self):<br />&nbsp;&nbsp;&nbsp; SGMLParser.reset(self)<br />&nbsp;&nbsp;&nbsp; self.urls = []<br /><br />&nbsp; def start_a(self, attrs):<br />&nbsp;&nbsp;&nbsp; href = [v for k, v in attrs if k=='href']<br />&nbsp;&nbsp;&nbsp; if href:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #print href<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if href[0].find(&quot;/member/mail.php&quot;) != - 1:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.urls.extend(href)

Extending SGMLParser – if it finds an <a> tag it will run the start_a method I and do what I want.

This little class will stick all of these URLs (which have an href of the form /member/mail.php&id=1234) into the urls list. Note the v for k with the if statement, this lovely one liner is why I like Python so much. The only problem is that it returns a list which will only have one element. I’m sure there’s a way of changing the one-liner but I don’t know what it is yet. Still, think of the equivalent Java, or PL/SQL! Having to reference the first element of the returned list is a small price to pay for this expressive power. Of course, some Python god will say I’m talking out of my rear end and I just need to do …, whatever that is.

Next I need to forward this mail. This is quite complex because I need to get the page displaying the forward, parse out the text of the mail and any other arguments, and then submit this as a post command back to the web server afdter substituting my forward mail into the string.

class getMailBody(SGMLParser):

def reset(self):
SGMLParser.reset(self)
self.data = ""
self.inForm = 0
self.inTextArea = 0
self.textAreaName = ""
self.textAreaID = ""
self.textAreaText = []

def start_form(self, attrs):
theForm = [v for k, v in attrs if k==‘action’]
if theForm:
self.inForm = theForm0.find("/member/send_mail.php") != – 1

def end_form(self):
self.inForm = 0

def getValue( self, val, attrs ):
return [v for k, v in attrs if k==val]

def appendData(self,value):
amp = ""
if self.data:
amp = "&"
self.data = amp + value

def processAttribs(self,attrs):
if self.inForm:
name = self.getValue(‘name’,attrs)
idVal = self.getValue(‘id’,attrs)
value = self.getValue(‘value’,attrs)
if not value:
value.append( "" )
if name:
# print "name" + name0
self.appendData( urlencode( {name0:value0 } ))
if idVal and idVal != name:
# print "idval" + idVal0
self.appendData( urlencode( {idVal0:value0 } ) )

def start_input(self, attrs):
self.processAttribs( attrs )

def start_textarea(self, attrs):
if self.inForm:
self.textAreaName = self.getValue(‘name’,attrs)
self.textAreaID = self.getValue(‘id’,attrs)
self.inTextArea = 1

def end_textarea(self):
if self.inTextArea:
self.inTextArea = 0
if self.textAreaName:
# print "text area name" + self.textAreaName0
self.appendData( urlencode( {self.textAreaName0:" ".join(self.textAreaText) } ))
if self.textAreaID and self.textAreaID != self.textAreaName:
# print "text area idval" + self.textAreaID 0
self.appendData( urlencode( {self.textAreaID0:" ".join(self.textAreaText ) } ))

def handle_data(self,text):
if self.inTextArea:
self.textAreaText.append( text)
#print text

This class will parse the forward mail page out into the data member so that I can then use it to send an http post request to the remote server, thus:

def forwardMail(url):

replyTag = "/member/reply.php"

# of the form /member/mail.php?id=3298
splitURL = url.split("?")

data = "%s&btn=Forward" % splitURL1
request = ClientCookie.Request(macMailURL + replyTag)
response = ClientCookie.urlopen(request,data)
page = response.read()
#print page
mb = getMailBody()
mb.feed(page)
mb.close()
forwardTag = "/member/send_mail.php"
data = mb.data.replace("to=","[email protected]")
request = ClientCookie.Request(macMailURL + forwardTag)
response = ClientCookie.urlopen(request,data)
page = response.read()

Of course, replacing fred with your mail. I’ll leave working this out to the reader.

Macmail does delete though the move command. I reused the urllist from the last page:

def deleteMail(urlList):
deleteTag="/member/move.php"
amp = ""
deleteData = []
for val in urlList:
bits = val.split("=")
#print bits
theID = bits1
deleteData.append(theID)
data = "delete[]=" + "&delete[]=".join(deleteData)
#print data
request = ClientCookie.Request(macMailURL + deleteTag)
response = ClientCookie.urlopen(request,data)
return response.read()

This will return the next page after all of the mail displayed on the current one is deleted.  Here we glue it all together:

###################################
# Processing body
###################################

page = login2Macmail()

while True:
parser = collectTags()
parser.feed(page)
parser.close()
if not parser.urls:
break
for url in parser.urls:
forwardMail(url)

# Submit delete request for all URL’s from first page
# get page again

page = deleteMail(parser.urls)

#print page

## Now delete all sent mail

request = ClientCookie.Request(macMailURL + "/member/index.php?folder=SentItems")
response = ClientCookie.urlopen(request)
page = response.read()

while True:
parser = collectTags()
parser.feed(page)
parser.close()
if not parser.urls:
break

page = deleteMail(parser.urls)

#print page

request = ClientCookie.Request(macMailURL + "/member/empty_trash.php")
response = ClientCookie.urlopen(request)
page = response.read()

This little control block loops through all of the inbox pages until there are no more mail viewing url’s left, as it goes it deletes them all. Then it goes to the outbox and deletes all of that, then it calls the empty trash function to be polite. I don’t want to leave a load of junk on that server, the mail account has been very useful over the years and I wouldn’t like to annoy the people running it.

For the record, the import statement at the top is this:

import ClientCookie, urllib2
from sgmllib import SGMLParser
import htmlentitydefs
import sys
from urllib import urlencode

Have fun, and don’t eat too much Java, it’s bad for you and takes too long, life is short, use proper powerful tools.