Re: print function and unwanted trailing space

2013-09-12 Thread Albert Hopkins


On Wed, Sep 11, 2013, at 07:36 AM, Wayne Werner wrote:
 On Sat, 31 Aug 2013, candide wrote:
  # -
  for i in range(5):
 print(i, end=' ')   # - The last ' ' is unwanted
  print()
  # -
 
 Then why not define end='' instead?

I think the OP meant that ' ' is wanted up until the final item.. so
something like

for i in range(4):
print(i, end=' ')
print(4)

or, better:
print(' '.join(str(i) for i in range(5)))
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-09-11 Thread Wayne Werner

On Sat, 31 Aug 2013, candide wrote:

# -
for i in range(5):
   print(i, end=' ')   # - The last ' ' is unwanted
print()
# -


Then why not define end='' instead?

-W
--
https://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread Andreas Perstinger

On 31.08.2013 10:17, candide wrote:


What is the equivalent in Python 3 to the following Python 2 code:

# -
for i in range(5):
  print i,
# -

?


How about

 print( .join(str(i) for i in range(5)))
0 1 2 3 4

Bye, Andreas



--
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread candide

Le 31/08/2013 10:43, Andreas Perstinger a écrit :

 How about

   print( .join(str(i) for i in range(5)))
 0 1 2 3 4



Thanks for your answer. The output is stricly the same but the code 
doesn't suit my needs :


1) I'm porting to Python 3 a Python 2 full beginner course : the 
learners are not aware of the join method nor the str type nor 
generators stuff;
2) Your code introduce a (sometimes) useless conversion to str (consider 
a string instead of range(5)).



--
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread Peter Otten
candide wrote:

 Le 31/08/2013 10:43, Andreas Perstinger a écrit :
 
   How about
  
 print( .join(str(i) for i in range(5)))
   0 1 2 3 4
  
 
 
 Thanks for your answer. The output is stricly the same but the code
 doesn't suit my needs :
 
 1) I'm porting to Python 3 a Python 2 full beginner course : the
 learners are not aware of the join method nor the str type nor
 generators stuff;
 2) Your code introduce a (sometimes) useless conversion to str (consider
 a string instead of range(5)).

You are out of luck, the softspace mechanism, roughly

softspace = False
for i in range(5):
if softspace:
print(end= )
print(i, end=)
softspace = True
print()

with `softspace` saved as a file attribute, is gone in Python3. But I don't 
think that someone who doesn't know it existed will miss the feature.

Maybe you can allow for /some/ magic and introduce your students to

print(*range(5))

early-on.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread Steven D'Aprano
On Sat, 31 Aug 2013 10:17:23 +0200, candide wrote:

 What is the equivalent in Python 3 to the following Python 2 code:
 
 # -
 for i in range(5):
  print i,
 # -
 
 ?
 
 Be careful that the above code doesn't add a trailing space after the
 last number in the list, 

Of course it does. Have you actually tried it? The interactive 
interpreter is tricky, because you cannot directly follow a for-loop with 
another statement. If you try, the interactive interpreter gives you an 
indentation error. But we can work around it by sticking everything 
inside an if block, like so:

py if True:
... for i in range(5):
... print i,
... # could be pages of code here
... print FINISHED
...
0 1 2 3 4 FINISHED


Or you could stick the code inside an exec, which doesn't have the same 
limitation as the interactive interpreter. This mimics the behaviour of 
code in a file:

py exec for i in range(5):
... print i,
... print FINISHED
... 
0 1 2 3 4 FINISHED


The same results occur with any other Python 2.x, and indeed all the way 
back to Python 1.5 and older.


 hence the following Python 3 code isn't strictly equivalent:
 
 
 # -
 for i in range(5):
  print(i, end=' ')   # - The last ' ' is unwanted
 print()


The last space is exactly the same as you get in Python 2. But really, 
who cares about an extra invisible space? In non-interactive mode, the 
two are exactly the same (ignoring the extra print() call outside the 
loop), but even at the interactive interpreter, I'd like to see the code 
where an extra space makes a real difference.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread Ned Batchelder

On 8/31/13 4:17 AM, candide wrote:


What is the equivalent in Python 3 to the following Python 2 code:

# -
for i in range(5):
print i,
# -

?

Be careful that the above code doesn't add a trailing space after the 
last number in the list, hence the following Python 3 code isn't 
strictly equivalent:



# -
for i in range(5):
print(i, end=' ')   # - The last ' ' is unwanted
print()
# -


For a beginner course, the trailing space is fine, use this code. 
They'll never notice the trailing space (I wouldn't have!) and to 
explain why the comma leaves off the last one takes a really advanced 
understanding of obscure details anyway.


--Ned.
--
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread Peter Otten
Steven D'Aprano wrote:

 On Sat, 31 Aug 2013 10:17:23 +0200, candide wrote:
 
 What is the equivalent in Python 3 to the following Python 2 code:
 
 # -
 for i in range(5):
  print i,
 # -
 
 ?
 
 Be careful that the above code doesn't add a trailing space after the
 last number in the list,
 
 Of course it does. Have you actually tried it? The interactive
 interpreter is tricky, because you cannot directly follow a for-loop with
 another statement. If you try, the interactive interpreter gives you an
 indentation error. But we can work around it by sticking everything
 inside an if block, like so:
 
 py if True:
 ... for i in range(5):
 ... print i,
 ... # could be pages of code here
 ... print FINISHED
 ...
 0 1 2 3 4 FINISHED
 
 
 Or you could stick the code inside an exec, which doesn't have the same
 limitation as the interactive interpreter. This mimics the behaviour of
 code in a file:
 
 py exec for i in range(5):
 ... print i,
 ... print FINISHED
 ... 
 0 1 2 3 4 FINISHED
 
 
 The same results occur with any other Python 2.x, and indeed all the way
 back to Python 1.5 and older.

Your test is flawed. The softspace mechanism ensures that there is a space 
*between* all printed items, but not *after* the last printed item.

print FINISHED

will add a space while

print

will not. Compare:

 with open(tmp.txt, w) as f:
... for i in range(3): print  f, i,
... print  f
... 
 open(tmp.txt).read()
'0 1 2\n'
 with open(tmp.txt, w) as f:
... for i in range(3): print  f, i,
... print  f, FINISHED
... 
 open(tmp.txt).read()
'0 1 2 FINISHED\n'




-- 
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread Oscar Benjamin
On 31 August 2013 12:16, Steven D'Aprano
steve+comp.lang.pyt...@pearwood.info wrote:
 On Sat, 31 Aug 2013 10:17:23 +0200, candide wrote:

 What is the equivalent in Python 3 to the following Python 2 code:

 # -
 for i in range(5):
  print i,
 # -

 ?

 Be careful that the above code doesn't add a trailing space after the
 last number in the list,

 Of course it does. Have you actually tried it? The interactive
 interpreter is tricky, because you cannot directly follow a for-loop with
 another statement. If you try, the interactive interpreter gives you an
 indentation error. But we can work around it by sticking everything
 inside an if block, like so:

 py if True:
 ... for i in range(5):
 ... print i,
 ... # could be pages of code here
 ... print FINISHED
 ...
 0 1 2 3 4 FINISHED

The space is added by the final print statement, not the last one in
the loop. Here's a demo that shows this:

$ cat print.py
for i in range(5):
print i,
print
$ cat print3.py
for i in range(5):
print(i, end=' ')
print()
$ py -2.7 print.py | cat -A
0 1 2 3 4^M$
$ py -3.3 print3.py | cat -A
0 1 2 3 4 ^M$

(Notice the space between the 4 and ^M (which is cat's way of saying '\r').

[snip]

 hence the following Python 3 code isn't strictly equivalent:


 # -
 for i in range(5):
  print(i, end=' ')   # - The last ' ' is unwanted
 print()

 The last space is exactly the same as you get in Python 2. But really,
 who cares about an extra invisible space? In non-interactive mode, the
 two are exactly the same (ignoring the extra print() call outside the
 loop), but even at the interactive interpreter, I'd like to see the code
 where an extra space makes a real difference.

I seem to remember it breaking some unit test or doc test something
when I first tried to port something using 2to3 (this is the
replacement that 2to3 uses for print with a trailing comma). It's not
so important for interactive terminal output but when you do 'python
script.py  output.dat' the unwanted space shouldn't be there. The
soft-space feature is useful but stateful as Peter says and defies the
normal concept of what happens when calling a function so it was
removed when print became a function.


Oscar
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread candide

Le 31/08/2013 13:16, Steven D'Aprano a écrit :



Of course it does. Have you actually tried it?



Of course I did, redirecting the output to a file in order to spot an 
eventually trailing space. I did the same for the Python 3 code.

--
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread candide

Le 31/08/2013 12:31, Peter Otten a écrit :
 softspace = False
 for i in range(5):
  if softspace:
  print(end= )
  print(i, end=)
  softspace = True
 print()


The if instruction imposes useless testing (we know in advance the 
problem to occur at the very end of the loop) and useless writing 
(writing '').


The following is clearer

# -
n=5
for i in range(n-1):
print(i, end=' ')
print(n-1)
# -


but doesn't solve all the cases (imagine a string or an iterator).
--
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread candide

Le 31/08/2013 13:24, Ned Batchelder a écrit :


For a beginner course, the trailing space is fine, use this code.


I was really expecting there was a trick but I'll follow your advice, 
after all the trailing space is invisible!


Nevertheless, this can be quite annoying. For instance, some automated 
program testing (cf. http://www.spoj.com/, http://acm.timus.ru/, etc) 
expect the exact output to get accepted, no byte more or a byte less.






--
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread Peter Otten
candide wrote:

 Le 31/08/2013 12:31, Peter Otten a écrit :
   softspace = False
   for i in range(5):
if softspace:
print(end= )
print(i, end=)
softspace = True
   print()
 
 
 The if instruction imposes useless testing (we know in advance the
 problem to occur at the very end of the loop) and useless writing
 (writing '').

To make it crystal clear, the above was to illustrate the algorithm used in 
Python 2, not a suggestion. Python 2 uses that useless testing -- which is 
cheap compared to actual I/O.

 The following is clearer
 
 # -
 n=5
 for i in range(n-1):
  print(i, end=' ')
 print(n-1)
 # -
 
 
 but doesn't solve all the cases (imagine a string or an iterator).

I still think you should live with a trailing space or go with my actual 
suggestion

print(*range(5))

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread Steven D'Aprano
On Sat, 31 Aug 2013 14:59:17 +0200, candide wrote:

 Le 31/08/2013 13:16, Steven D'Aprano a écrit :
 
 
 Of course it does. Have you actually tried it?
 
 
 Of course I did, redirecting the output to a file in order to spot an
 eventually trailing space. I did the same for the Python 3 code.


Fair enough. Seems like the print statement implementation in Python 2 is 
uglier than I imagined, keeping hidden state between invocations.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread Chris Angelico
On Sat, Aug 31, 2013 at 11:33 PM, candide candide@free.invalid wrote:
 The if instruction imposes useless testing (we know in advance the problem
 to occur at the very end of the loop) and useless writing (writing '').

 The following is clearer

 # -
 n=5
 for i in range(n-1):
 print(i, end=' ')
 print(n-1)
 # -


 but doesn't solve all the cases (imagine a string or an iterator).

Similar but maybe simpler, and copes with more arbitrary iterables:

it=iter(range(5))
print(next(it), end='')
for i in it:
print('',i, end='')

Also guarantees to use 'sep' between the elements, fwiw.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread Oscar Benjamin
On 31 August 2013 16:30, Chris Angelico ros...@gmail.com wrote:

 but doesn't solve all the cases (imagine a string or an iterator).

 Similar but maybe simpler, and copes with more arbitrary iterables:

 it=iter(range(5))
 print(next(it), end='')
 for i in it:
 print('',i, end='')

If you want to work with arbitrary iterables then you'll want

it = iter(iterable)
try:
val = next(it)
except StopIteration:
pass  # Or raise or something?
else:
print(val, end='')
for i in it:
print('', i, end='')


Oscar
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread candide

Le 31/08/2013 12:31, Peter Otten a écrit :


with `softspace` saved as a file attribute, is gone in Python3.



After reading

http://docs.python.org/3.0/whatsnew/3.0.html#print-is-a-function


I understand what you meant by softspace. Thanks.

--
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread candide

Le 31/08/2013 15:59, Peter Otten a écrit :




To make it crystal clear, the above was to illustrate the algorithm used in
Python 2, not a suggestion.



Ok sorry, I misinterpreted.




 I still think you should live with a trailing space


Are you sure ? The following code

#--
import io

output = io.StringIO()
n=5
for i in range(n-1):
print(i, end=' ', file=output)
print(n-1, file=output)
print(output.getvalue().count(' '))
#--


outputs 4, the correct number of space character.



 or go with my actual
 suggestion

 print(*range(5))



It's a very good suggestion (the best one in fact) but rather 
complicated to explain to pure novices in programming.


--
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread Chris Angelico
On Sun, Sep 1, 2013 at 1:43 AM, Oscar Benjamin
oscar.j.benja...@gmail.com wrote:
 On 31 August 2013 16:30, Chris Angelico ros...@gmail.com wrote:

 but doesn't solve all the cases (imagine a string or an iterator).

 Similar but maybe simpler, and copes with more arbitrary iterables:

 it=iter(range(5))
 print(next(it), end='')
 for i in it:
 print('',i, end='')

 If you want to work with arbitrary iterables then you'll want

 it = iter(iterable)
 try:
 val = next(it)
 except StopIteration:
 pass  # Or raise or something?
 else:
 print(val, end='')
 for i in it:
 print('', i, end='')

I went with this version:

except StopIteration:
raise

In other words, if it's going to bomb, let it bomb :)

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread Joshua Landau
On 31 August 2013 23:08, Chris Angelico ros...@gmail.com wrote:
 On Sun, Sep 1, 2013 at 1:43 AM, Oscar Benjamin
 oscar.j.benja...@gmail.com wrote:
 On 31 August 2013 16:30, Chris Angelico ros...@gmail.com wrote:

 but doesn't solve all the cases (imagine a string or an iterator).

 Similar but maybe simpler, and copes with more arbitrary iterables:

 it=iter(range(5))
 print(next(it), end='')
 for i in it:
 print('',i, end='')

 If you want to work with arbitrary iterables then you'll want

 it = iter(iterable)
 try:
 val = next(it)
 except StopIteration:
 pass  # Or raise or something?
 else:
 print(val, end='')
 for i in it:
 print('', i, end='')

 I went with this version:

 except StopIteration:
 raise

 In other words, if it's going to bomb, let it bomb :)

I think the point is that StopIteration is an unsafe error to raise.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: print function and unwanted trailing space

2013-08-31 Thread Terry Reedy

On 8/31/2013 7:15 PM, Joshua Landau wrote:

On 31 August 2013 23:08, Chris Angelico ros...@gmail.com wrote:

On Sun, Sep 1, 2013 at 1:43 AM, Oscar Benjamin
oscar.j.benja...@gmail.com wrote:

On 31 August 2013 16:30, Chris Angelico ros...@gmail.com wrote:


but doesn't solve all the cases (imagine a string or an iterator).


Similar but maybe simpler, and copes with more arbitrary iterables:

it=iter(range(5))
print(next(it), end='')
for i in it:
 print('',i, end='')


If you want to work with arbitrary iterables then you'll want

it = iter(iterable)
try:
 val = next(it)
except StopIteration:
 pass  # Or raise or something?
else:
 print(val, end='')
for i in it:
 print('', i, end='')


I went with this version:

except StopIteration:
 raise

In other words, if it's going to bomb, let it bomb :)


I think the point is that StopIteration is an unsafe error to raise.


It should only be raised by iterator.__next__ method and caught by 
iterator user and not re-raised. Raise something like ValueError('empty 
iterable') from None instead.



--
Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list