# 'complex' function with string argument.

Steven D'Aprano steve at pearwood.info
Tue Mar 18 05:52:35 CET 2014

```On Mon, 17 Mar 2014 11:18:56 -0500, Mark H Harris wrote:

> How should one spell a complex number? Should we use i or j ? Should the
> imaginary part be set off somehow?  Should literals be parsed
> differently (or consistently) with correctly formed strings?  Who knows,
> beats me.

With respect, that's just because you would make a lousy language
designer :-) The answer to most of those questions should be pretty
obvious, with perhaps just one that isn't clear.

"How should one spell a complex number?" There is perfectly good syntax
for complex numbers used by mathematicians and engineers for over a
century. There is no need to invent something different just for the sake
of being different:

Yes:   2+3i or 2+3j
No:    @2|3?

"Should we use i or j ?" There are good reasons for both i and j. This
one comes down to personal preference.

"Should the imaginary part be set off somehow?" What do you mean "set
off"? Why do you want to? Since the imaginary part can appear on its own:

z = 3j

we cannot make "setting off" compulsory. Once you have syntax for complex
numbers with an imaginary component, everything else Just Works with no

z = 2 + 3j  # an expression adding 2 to 3j
z = 5*3j  # an expression multiplying 5 by 3j

There's no need for dedicated syntax for complex numbers beyond the
arithmetic expressions, so there actually isn't need to parse complex
literals beyond the j suffix.

"Should literals be parsed differently (or consistently) with correctly
formed strings?" Once you decide that complex literals should be formed
from only the imaginary part, 3j, parsing literals is simple. So is
passing strings: you have something that looks like a float, with a j
suffix. Obviously they should parse the same.

assert 1.234j == complex('1.234j')

Problem solved.

Well, not quite -- it would be rather limiting if the complex constructor
only accepted complex numbers with an implicitly zero real part. We'd
like to accept anything that repr(z) can print. Since repr(z) prints
complex numbers with a + or - infix operator, the complex constructor
should accept the same inside strings.

How flexible should the complex constructor be? Should it bend over
backwards to accept any mathematical expression that includes a complex j
suffix, e.g. complex("2**3i")? I think not, since complex numbers don't
display like that. Our only obligation is to parse the strings that
complex.__repr__ can produce, not to parse any imaginable numeric
expression.

So at a minimum, complex should accept strings that look like

<float>j
<float>+<float>j
<float>-<float>j

For the same reason that float("2") works, we should also allow strings
that look like:

<float>

with no j suffix. Anything else, including spaces around the + and -
symbols, would be a bonus.

> consider:
>  >>> complex( 3   +  2   j)
> SyntaxError: invalid syntax

That's a syntax error for the same reason that:

x = 1   2

is a syntax error. Nothing to do with the + sign. It's the spaces between
the 2 and the j.

>  >>> complex( 3   +2j  )
> (3+2j)
>  >>>
> I don't know... you tell me.

In both cases, the call to complex is redundant. You've already created a
complex number, using syntax, then you pass it to the complex function
which just returns the same number.

>  >>> complex('3+2j')
> (3+2j)
>  >>> complex('3 +2j')
> Traceback (most recent call last):
>    File "<pyshell#17>", line 1, in <module>
>      complex('3 +2j')
> ValueError: complex() arg is a malformed string

Personally, I would like complex to accept spaces around the + or -, as
it already accepts leading and trailing spaces. But it's not a big deal.

[...]
> Also, philosophically, C ignores white space;  python does not.

C does not ignore whitespace.

forwhile

is not the same as

for while

The first is a valid identifier, the second is a syntax error. Oh
somebody please tell me it's not a valid C expression! *wink*

--
Steven

```