[Tutor] Trickier exercise: convert string to complex number

Angus Rodgers angusr at bigfoot.com
Sat Jul 11 15:03:08 CEST 2009


>Date: Sat, 11 Jul 2009 14:33:58 +1000
>From: Lie Ryan <lie.1296 at gmail.com>
>Message-ID: <h394oi$eru$1 at ger.gmane.org>
>
>Err... what's the question? Are you asking for style checking or the
>mentioned "bugs" in the comments?

Mainly style checking (but more generally anything silly that I'm
doing, that might leap to somebody's eye).  Any time my coding (or
in this case, mainly my commenting!) gets more elaborate (because,
in this case, I had to think harder about this exercise than about
any of the previous ones), I feel a need for somebody to look over
my shoulder, to make sure that I'm not starting to go haywire.

I was fairly pleased with the solution (because it would have been
easy to have coded something a lot more complicated and confusing)
- but also worried that I might have no good reason to be pleased!

I worry that I may be developing a silly and overly fussy style.

I tend to get obsessed with trivia, and fail to see the wood for
the trees.  On the other hand, I'm trying to discipline myself
to do even small exercises in a way that will scale up to larger
ones.

I'm trying to keep my idiosyncrasies in check, but there's no 
substitute for an external check now and then, to ensure that
I'm getting the balance at least roughly right.

>_const_func = lambda c : (lambda x : c)
>...
>def get_val(typ, prompt=None, valid=_const_func(True)):
>   ...
>
>I think that is an over-generalisation. It is much simpler to read
>def get_val(typ, prompt=None, valid=lambda x: True):
>
>because other people reading your code might not know what _const_func
>do (whether it is simply returning a lambda or it does something more
>complex).

That's a good point, and I'll change this.  (Reverting to how it
was before!  I imagined adding '_const_func' was an improvement.)

>> # A bug in this program is that, by indiscriminately removing all
>> #
>> # whitespace before processing, it fails to catch certain errors,
>> #
>> # e.g. " - 1 2 " will be passed to float("-12").  Correcting this
>> #
>> # bug is likely to make the program considerably more ... complex.
>
>You can avoid that bug by not stripping whitespaces. Ignore them inside
>the loop (put if ch == '': break) and before passing the number to
>float, compare the number's length before and after the whitespace is
>stripped. Not really considerably more complex...

D'oh!  How true.

I haven't coded this exactly as you suggested (no explicit check for
internal whitespace, and no length comparison, either), but it seems
to be roughly OK (although my testing hasn't been thorough, and I
may have introduced new bugs). float() itself strips initial and
final whitespace, so my program doesn't have to worry about that.

def atoc(num):
    """Convert string representation to complex number."""
    # The algorithm still assumes there is no initial or final
    # whitespace
    num = num.strip()
    n = len(num)
    if not n:
        raise ValueError
    # Ignore first character (now initial whitespace has been 
    # stripped)
    for i, ch in enumerate(num[1:]):
        if ch == 'j':
            # Must be end of string (now final whitespace has been
            # stripped)
            if i != n - 2:
                raise ValueError
            # Case (ii)
            return complex(0.0, float(num[:-1]))
        if ch in '+-' and num[i] not in 'eE':
            if num[-1] != 'j' or num[-2].isspace():
                raise ValueError
            if ch == '+':
                # Case (iii)
                return complex(float(num[:i + 1]), 
                               +float(num[i + 2:-1]))
            if ch == '-':
                # Case (iv)
                return complex(float(num[:i + 1]), 
                               -float(num[i + 2:-1]))
    # Case (i)
    return complex(float(num), 0.0)

(I have manually wrapped a few longish lines, just for this post
to the mailing list - the longest was 76 characters long.  I've
also corrected another bug that was in the original program - it
didn't check that the final [non-space] character was actually a
'j'.)
-- 
Angus Rodgers


More information about the Tutor mailing list