As a throwaway diagram in a piece of teaching material I wanted to visualise the structure of a Python dict. One tool I use for generating simple block diagrams is BlockDiag. This uses a simple notation for generating box and arrow diagrams:
So how can we get the key structure from a nested Python dict in that form? There may well be a Python method somewhere for grabbing this information, but it was just a quick coffee break puzzle to write a thing to grab that data and represent it as required:
def getChildren(d,t=None,root=None): if t is None: t=[] if root is None: for k in d: if isinstance(d[k],dict): t=getChildren(d[k],t,k) else: for k in d: t.append('"{root}" -> "{k}";'.format(root=root,k=k)) if isinstance(d[k],dict): t=getChildren(d[k],t,k) return t r={'a':{'b':1, 'c':{'d':2,'e':3}}} print('{{ {graph} }}'.format(graph='\n'.join(getChildren(r)))) #------ { "a" -> "b"; "a" -> "c"; "c" -> "d"; "c" -> "e"; }
There are probably better ways of doing it*, but that’s not necessarily the point. Which is a point I realised chatting to a colleague earlier today: I’m not that interested in the teaching of formal computing approaches as a way of training enterprise developers. Nor am I interested in the teaching of computing through contrived toy examples. What I’m far more interested in is helping students do without us; and students, at that, who have end-user computing needs that they want to be able to satisfy in whatever domain they end up in.
- So, for example:
def getChildren(d,t=None,root=None): if t is None: t=[] if root is None: for k in d: if isinstance(d[k],dict): t=getChildren(d[k],t,k) else: for k in d: s='"{root}" -> "{k}";'.format(root=root,k=k) if s not in t: t.append(s) if isinstance(d[k],dict): t=getChildren(d[k],t,k) return t r={'a':{'b':1, 'c':{'d':2,'e':3}}} l=[r,{'a':{'b':1, 'c':{'e':3}}}] o=[] for z in l: o=getChildren(z,o) o #['"a" -> "b";', '"a" -> "c";', '"c" -> "d";', '"c" -> "e";']
Which is to say, not (in the first instance) enterprise level, production quality code. It’s code to get stuff done. End-user application development code. Personal, disposable/throwaway, ad hoc productivity tool development. Scruffy code that lets you use bits of string and gaffer tape and chunks of other people’s code to solve a particular problem.
But that’s not to say the code has to stay ropey… In testing the first attempt at the above code, it lacked the guards that checked whether a variable was a dict
, at which point it failed whenever a literal value was encountered. There may well be other things that are broken about it but I can fix those as they crop up (because I know the sort of output I expect to see*, and if I don’t get it, I can try to fix it.) I also had to go and look up how to include literal curly brackets in a python formatted string (double them up) for the print statement. But that’s okay. That’s just syntax… Knowing that I should be able to print the literal brackets was the important thing… And that’s all part of what I think a lot of our curriculum lacks – enthusing folk, making them curious, getting them to have expectations about what is and isn’t and should be possible**, and then being able to act on that.
* informal test driven end user software application development…?!;-)
** with some personal ethics about what may be possible but shouldn’t be pursued and should be lobbied against…