Changing code

December 29, 2008

Fun to speech

Filed under: Coding — Tags: , — Roberto Liffredo @ 11:41 pm

import win32com.client
reader = win32com.client.Dispatch("sapi.spvoice")
reader.Speak ("hello, world")

As a matter of facts, this trick is pretty old – at least, as old as Windows XP.
But it is the kind of discover that amuses me like a little boy :-)

April 18, 2008

Developer tests

Filed under: Coding, Software design — Roberto Liffredo @ 1:24 am

devtesting

Everybody knows what unit testing is.
Well, maybe not. Actually, in most environments, unit tests are a kind of empty “enterprise” word.

Unit test, in their “purest” idea, should test small unit of code (a function, an object, a file, a package) in perfect isolation; usually, this requires the use of stubs or other kind of fake objects.
Of course, we have to be pragmatic; sometimes, a unit is somewhat bigger than it should, and often it unit will embed a complex system, like a database.

In any case, the main advantage of a unit test is that it exactly pinpoints the source of the error, without the need of complex analysis or debugging sessions. This advantage obviously decreases with the complexity of the system.

That said, unit testing is only one of the possible test practices. With some simplification, we may classify them in the following way:

  • Unit tests
    Focus is on a development unit and its interface.
  • Integration tests
    Focus is on integration between components (like a class and a database) and their integration.
  • Functional tests
    Focus is on complete functionalities of the program, from a user-perspective.

All of these tests have one trait in common: they are developer tests, or tests written by software developers.
We need functional tests, in order to check a feature in its “real” environment.
We need integration tests, in order to work out all possible issues deriving from integrations.
We need unit tests, because they are able to pinpoint exactly an error in a very small unit of code.

All those tests help in raising software quality, and for this reason we should go for all of them, whenever possible.
Of course, this approach may be quite expensive; therefore, we should always have a clear idea of testing scope, in particular what we should test, and when we should run a test.
JUnit website makes it quite clear: we should test what could reasonably break, and we should run tests every time code is changed.
How this translates into actual projects, depend on several factors; my own suggestions is to take it as literal as possible, because it will greatly enhance the developer confidence in the final code, and finally lower the total effort for software development and maintenance.

Some further reading:

March 31, 2008

Debugging with Pydev Extension

Filed under: Coding, Tools — Roberto Liffredo @ 1:59 pm

Without any doubt, Pydev Extension is a wonderful environment for Python development.
One of the nicest features is the “remote debugger”, that allows attaching to every python script, even if it was not launched from Eclipse; actually, where I work this was the “killer feat” that convinced management over buying it.

Here is a very rough instruction for its usage (more details):

  1. Add the directory containing the module pydevd to the PYTHONPATH environment variable. Note: actual path may change, reflecting the Pydev version installed.
      set PYTHONPATH=%PYTHONPATH%;C:\eclipse\plugins\org.python.pydev.debug_1.3.14\pysrc
  2. From Eclipse, start Python debugging server
  3. Add the following instructions to the python script
      import pydevd
      pydevd.settrace()
  4. Execute the script; when hitting the lines above, it will break and connect to Eclipse environment. From there on, you can set breakpoints, inspect variables, and use all standard debugging techniques.

In my opinion, these steps are a bit cumbersome: especially changing the PYTHONPATH sounds a bit as a hack, and actually may be even impossible, for instance, when using python within a service.
However, regarding the last point there is a solution: because while importing modules Python uses the sys.path list, which is in turn initialized from PYTHONPATH environment variable.
Knowing that, here is a slightly longer suggestion that allows for including pydevd without any modification of the environment:

def pydevBrk():
  pydevdPath = r“C:\eclipse\plugins\org.python.pydev.debug_1.3.14\pysrc”
  import sys
  if not pydevdPath in sys.path:
    sys.path.append(pydevdPath)
  try:
    import pydevd
    pydevd.settrace()
  except ImportError:
    pass # Most probably, pydev is not installed on the system

A small advantage of this variant, it fail gracefully even in case pydev is not installed on the system – in other words, if for some reason debug code makes its road to production, it will not crash the entire application.
Of course, in this case the initial breakpoint will stop inside the function, and not where it is being called.

A final note about pydevd.settrace(): there are several parameters, which may be very useful, as the described in the docstring:

@param host: the user may specify another host, if the debug
    server is not in the same machine
@param stdoutToServer: when this is true, the stdout is passed
    to the debug server
@param stderrToServer: when this is true, the stderr is passed
    to the debug server so that they are printed in its
    console and not in this process console.
@param suspend: whether a breakpoint should be emulated as
    soon as this function is called.

Note: Remote debugging requires some further setup, in order to translate paths from the application to the server; this requires editing the module pydevd_file_utils (in the same folder as pydevd), and setting the translation table PATHS_FROM_CLIENT_TO_SERVER; although this is quite an easy and straightforward step, it has to be repeated for each new version of the plugin.

December 14, 2007

Memory management in python

Filed under: Coding, Software design — Tags: — Roberto Liffredo @ 6:03 pm

It is a quite common pitfall in python: trying to directly use knowledge gathered within other programming languages, like Java or .NET.
And, usually, ends with something like “Puah, I don’t like python”.

For instance, garbage collection.

Mainly, Python memory management is implemented through reference counting: as soon as the number of references of an object reaches zero, it is deleted. What “delete” means, then, depends on the actual implementation of the python VM.
CPython, for instance, uses delete the object: this means that the C++ destructor (or, in case of Python objects, the __del__ method) is called, and the memory may be released (or may return to a common pool handled directly by the python memory manager, in case of “simple” objects like integers); in other words, CPython uses deterministic finalizers.
However, this behavior is not guaranteed on other implementations, like JPython or IronPython, because of the different underlying memory model.

Reference counting has several advantages because it is easy to implement, fast, and predictable; on the other hand, it is not able to handle some cases, in particular circular references.
Circular references happens when items in a container maintain a reference to the container itself; in this particular situation, when the container goes out of scope its reference count will still remain higher than zero, and hence will cause a memory leak.
For this reason, since Python 2.0, there is a new module, called gc, that perform some garbage collecting.
Its main and sole purpose is to handle those particular situations, and does not change nothing on standard memory management.

Back to our initial problem, this is quite a big difference with, for instance, C#, where calling GC.Collect() will effectively deallocate all pending objects. In python, gc.collect() will simply run a “check” for circular references, and deallocate if necessary all pending object in such state.

This is the reason why, in case of problems with memory deallocation, calling gc.collect() in python is in most cases almost useless.
In python, such problems are symptoms of flaws in the design, and blaming the language because it does not behave like other certainly do not help fixing them.

November 14, 2007

Lambda expressions in Python

Filed under: Coding — Tags: — Roberto Liffredo @ 10:18 pm

lambda In python, lambda expressions are simply a quick way to create anonymous functions.

Their syntax is quite simple, and coherent with other python structures:
lambda x: expression(x)

that is equivalent to
def anon(x):
return expression(x)

Note that, although the name, goal, python lambda expressions are not equivalent to their synonyms in functional languages because of three main limitations, and thus cannot be used for “serious” functional programming:

  • Lambda functions may only contain expressions (no statements, hence no if/then/else constructs, for example).
  • Lambda functions are made of exactly one expression.
  • Lambda functions do not have any local storage.

That said, there are several tricks that will somewhat allow to overcome the above limitations; as all tricks, they should be used with extreme care.

So, when should we use lambda functions? Well, better never than often, and most of the times using lambda expressions is not a so good idea.
Because, although geek and cool, lambda expressions may seriously hinder code readability.

As a general rule, better avoid use of lambda expressions. There may be cases where having an anonymous function may be handy (like in a property getter/setter), but readability is much more important than a cool and compact code style.

The Shocking Blue Green Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.