Friday 22 April 2016

THE PYTHON HAS SPOKEN

Dick Pountain/Idealog256 /06 November 2015 13:09

One of the more frequent topics of this column has been my interest in programming, both as an important economic activity and, for me, a pleasing pastime: I refuse to call it a "hobby". My last such column was about Scratch, an innovative Lego-like visual programming language for teaching children (and adults) invented at MIT, and since then Kevin Partner has written an excellent PC Pro feature about Scratch (issue 253, p58, Nov 2015). In that column I confessed how I quickly I'd become hooked by Scratch's blocky metaphor, despite some major limitations, and at the very end mentioned that some Scratchers in Berkeley had extended the language to remove these limitations, and called it Snap! It was more or less inevitable that some wet weekend would arrive when I'd take a deeper, non-cursory look at Snap!, and when it did I was re-hooked several times over.

Snap! looks pretty much like Scratch, similar enough to execute most Scratch programs with little or no alteration, but it adds several missing features that make it a more grown-up language. In place of Scratch's table-like arrays it has dynamic lists as first-class, named objects; it has local variables, not merely globals like Scratch; and it supports "continuations" that enable you to pass one block as a parameter to another block, a feature from advanced functional languages like Scheme and Haskell. Given its similarity to Scratch, learning Snap! was, er, a snap and within a day I was looking for serious programs to convert. I settled on several I'd written several years ago in Ruby, including a visual matrix calculator and a visual simulation of a simple eco-system called "Critters". Both went easily into Snap! and worked well, "Critters" ending up as one single smallish block, thanks to the Scratch/Snap! concept of "sprites" (animated screen objects) which took care of all the graphics with no coding on my part.

Anyhow, the point I'm working up to is that this conversion job made a deep impression on me. It may not have escaped you that programming languages have something in common with religions, in that they can attract fanatical adherents who become impervious to criticism. My casual flip from Scratch to Snap! was a sort of apostasy and I'd enjoyed it, so I began sifting through my other Ruby projects, but in the process discovered the wreckage of an abandoned Poker program in Python. I'd flirted with Python back in 2002 but quickly abandoned it in favour of Ruby, on almost entirely aesthetic grounds. In those days I was a fanatical object-orientation nut and I hated Python's OOP syntax which involves prefixing  just about everything with "self", something that Ruby managed to do without.

I've become more ecumenical since, and that weekend of Snap! coding had revived my enthusiasm for Lisp-style list programming, so to my own surprise I decided to finish that Poker program in Python rather than convert it. I downloaded a more recent version, WinPython 64-bit 3.4.3, and set to work. Instead of pursuing the pure OOP architecture I'd started with - card as a class, hand as a class, player as a class and so on - I rewrote the lower levels using Python's "tuples" instead. Each card is just a tuple (facevalue, suit), while a deck is a 52-piece tuple of cards. Soon I'd rewritten the whole thing using only tuples and lists, and never mentioned a class until I reached the player level. My code shrank to half its size, ran many times faster, and more importantly it worked, which the original never had properly. (Crucial to this success was Python's  "list comprehension" construct, a fiendishly clever one-line trick for building lists by pattern matching).

This taught me a serious lesson, one that might help you too. Rigidly adhering to a single methodology can be counterproductive: recognise which tools are right for each job and use them, regardless of dogma. Cards, decks and hands didn't need or deserve to be objects (no inheritance required) while players did because they have many attributes like a hand, a bankroll, a strategy, a personality. When I wrote the original program in OOP style I'd actually obscured its structure, in favour of a class hierarchy the language imposed on me. I'll never stop claiming that good programming is an art, one in which an eye for structure is even more important than a head for logic. Factoring, that is breaking down your code into smaller chunks in the best way, and choosing the right data structures, are far closer to musical composition than they are to science. What a pity that, unlike mathematics which occasionally spawns a Hollwood movie, beauty in programming can only ever be recognised by a handful of fellow programmers.


Biog: Dick = [Idealog for Idealog in PCPro if editor_approval == True]


SOCIAL UNEASE

Dick Pountain /Idealog 350/ 07 Sep 2023 10:58 Ten years ago this column might have listed a handful of online apps that assist my everyday...