29 January 2009

Bad Python

I've seen quite a lot of bad Python, even though Python makes the Path of Good Code relatively easier to find than other languages where spaghetti is the result without extra discipline and years of dedicated study of the language on the part of the programmer. Such is the Tao of Perl. Much bad Python however is from programmers who only knew statically typed OO languages (Java/C++/C#) and have not yet grokked dynamic typing, first-class functions, pervasive use of iterators, properties, etc, leading to eyesores such as:
  • Accessors such as getDistance() and setDistance(), instead of using an attribute. In Python, attributes can be turned into properties later, preserving the class interface.
  • Asserting the type of every argument and returned value, taking up maybe 30% of the code itself and 80% of the unit test code. Checking is usually pointless because the interpreter itself will let you know if someduck didn't .quack() like a duck, and makes the code less flexible.
  • Uber-private attributes (for no good reason), going so far as to use double-underscores on each side, which are supposed to be reserved for language features.
  • Dozens of customising parameters in constructors, such as reversed and strip and maxlen - when passing in a general transform function would be so much more elegant and could do so much more than just reverse the strings that the class works with.
  • Delegates where first-class function will do.
  • Wrapping things classes when dicts and tuples would be cleaner.
Partly, the developers don't recognise the ways in which many Design Patterns become trivial in Python, to the extent that they are more like one-line idioms than chapter-worthy Patterns with capital "P". Singleton Pattern? Write a module. Iterator? It's fundamental to the language. Need a Factory Pattern? Write a function and thanks to dynamic typing you can substitute makedummywidget for the makewidget during testing.Flyweight objects or Command Dispatch? Just use a dictionary. See also Python Patterns. (correction: previously referred to Abstract Factory, which is is not a factory but a group of related factories, e.g. for widgets from a given UI toolkit). Besides bad habits acquired from static OO, one can write bad code, in any language with
  • Vague and misleading identifiers (topic of future post)
  • Massive 'god' classes
  • Source files having no discernable structure.
  • Awkward decompositions of function
    • Forces similar logic to be repeated in dozens of places
    • Prevents parts from being reused e.g. in unit tests
    • Prevents dependencies from being stubbed out e.g. in unit tests
    • Mixing logic with orthogonal aspects like error-handling and logging for a harder-to-maintain mess.
Oh well. I recently spent a day re-doing about 30% of the functionallity of 8,600 lines of someone elses Java-style Python into 200 lines of real Python to support the greater flexibility I needed. Code can be that bad. (later expanded to just under 300 lines thanks to feature creep) From the comments:

18 January 2009

Small investing is too much work

I'm not offering any financial advice here, just jotting down some thoughts I had while I was munching on Pick 'n Pay muesli for breakfast this afternoon wondering how on earth one is supposed to know when to sell unit trusts.   I don't even invest much (one unit trust, that's it).  Investing is buying a stake in a company, and according to Warren Buffet (I think), one is supposed to imagine that one is buying the whole company, and do the research commensurately before buying.

It's like buying a company, really. What that means, is that investing is a lot of work.  I spent three months researching before buying a car, having called up dozens of dealers and collated the offers the made, compared all of the 31 currently popular hatchbacks in SA on dozens of critera, went through hundreds of car ads and gotten a feel for car prices and feature trade-offs, visited the dealer I bought from on five separate occasions in two weeks, negotiated for a couple of hours spread out over a week - once I was sure I finally parted with quite a few months of labour-equivalence in money to obtain the car.  

Opportunity cost of research. Imagine having to put that much work in to pick a good company to buy (shares in). Big institutional investors really do throw that kind of effort into their investments.   The effort may not be worth it for a small investment.   Think: one must buy at least R10,000 of a share to reasonably make some profit after the cut from brokerage fees.  But to make a good investment takes hours of researching that company, along with dozens of other candidate.    That time has value too: the opportunity cost of spending it researching investments, instead of doing something else and enjoying life.   The monetary return on a small investment is not big enough to justify the expense of research.  For example, suppose one could put in 40 hours of research and monitoring over 6 months, and through that make a couple of purchases and sales in single shares that result in 20% profit over the 6 months.   However, suppose one only invested R20,000 due to risk profile, thus netting R4000 profit.  That's only R100/hour, before tax, for investing right at the limit of your risk tolerance.   One might need about R100,000 available to invest (being money that one can afford to lose without materially affecting ones standard of living now or in the future) before the payoff starts to make the share research worthwhile.

Investing vs gambling.  It takes a lot of work to make a good investment, and it follows that someone who buys a share they heard was good and hope it works out, would be better off with the slot machines at Grand West Casino.   Some friends and I in fact went out to Grand West last night.  Three of use quickly went through the money we'd loaded onto the cards (R30 for me), the fourth won about R140, and another guy won about R500 (he's probably going back to lose it all in future trips trying to repeat the experience).   So, now I know how to play slots, but I still don't get it.  We commented on how the people seemed really rude - totally oblivious to others, some with looks of desperation on their faces, others doing things like sweeping a finger across the screen before each bet, and skollies hanging around outside waiting for pickpocketing/snatching opportunities.    Ok that had nothing to do with shares, except that many people are effectively gambling with shares, not investing in them.

When to sell a unit trust?  With shares one of course needs a tight strategy complete with stop-losses, profit taking etc.  Sell this share to take profits at a strategic moment, do some research and pick the next share to invest in.  But unit trusts hold lots of shares - it's almost like an index fund, except trusting the fund manager to make better-than-index return through active management, even after fees - which is often not the case.   What's the point of selling one unit trust, only to buy another one which almost certainly invests in the same big companies as the first one?    One also sells out of a share when the research says its growth potential is reducing.   But for a unit trust, its like selling out of the market - you do with when the whole market is unlikely to make big gains, which is an exceptionally difficult thing to judge.  So, in a sense unit trusts are simpler to buy because somone else does the shares research, but they are much more complicated to know when to sell.

K, hope you enjoyed Graham's randomness for the day.

10 January 2009

Quake 3 Config

The new colleagues brought an after-work tradition of of playing the Quake 3 multiplayer first-person shooter computer game. Unfortunately I sucked at first. Main problems:
  1. Visibility: can't see through the gibs and shells. It felt like I was playing paintball.
  2. Mouse sensitivity: 8 times the default, jumping all over the place.
  3. Keybindings: annoying trying to change weapons or zoom.
  4. Camouflage: The blue "team" model really stands out. Switched to small brown player models like 'bones/bones'/
  5. Technique: had rocket and railgun wrong, didn't traverse the map properly or look around properly with the mouse.
My Quake 3 autoexec.cfg has the following tweaks:
  • turns off muzzle flash, shells, gun model, gibs/blood for visibility.
  • turns off level music to hear the other players.
  • sets toggles for gun model and HUD to clear distractions.
  • tunes mouse sensitivity just high enough to allow 180-degree flick
  • set up multiple zoom levels
  • turned off bob/roll for slightly steadier crosshair
  • selected the circle + dot crosshair (cross-style can obscure small targets)
  • allow both keyboard and mouse weapon cycling