3
\$\begingroup\$

I'm writing a twirling cursor, which is a cursor that twirls in place in the console. In Forth, this takes just 3 lines, whereas in Python3 I have this:

from time import sleep # sleep(sec)
import sys
def flash(c):
 """Shows character c momentarily."""
 # backspace (8ドル) and sleep(sec) keep it in place and slow enough to see
 print(c,end=""); sys.stdout.flush(); sleep(0.05); print(chr(0x8),end=""); sys.stdout.flush()
 return
def halftwirl():
 """Twirls the cursor in place half-way i.e. | / - \."""
 flash(chr(0x7C)); flash(chr(0x2F)); flash(chr(0x2D)); flash(chr(0x5C));
 return
def twirl(n):
 """Twirls cursor in place n times."""
 for i in range(2*n):
 halftwirl()
 return
# Programme
print(twirl.__doc__)
twirl(5)

Whilst this works, and is no different from Forth in terms of code structure (see the Forth below), it is still, to my eyes, quite verbose.

In Forth, where there is no expense in calling subroutines, one naturally does something like this:

\ Building Blocks
0x7C constant .| 
0x2F constant ./ 
0x2D constant .- 
0x5C constant .\ 
0x8 constant .del \ backspace delete
: flash ( c -- ) emit 50 ms .del emit ; \ show character momentarily
: half-twirl ( -- ) .| flash ./ flash .- flash .\ flash ; \ half-twirl cursor in place
: twirl ( n -- ) 0 do half-twirl half-twirl loop ; \ twirl cursor in place n times

Questions:

  1. Is the cost of calling subroutines in Python cheap enough to support refactoring, i.e. pulling out flash() as its own subroutine, halftwirl() as its own, and making twirl() call these within its inner loop?

  2. Is the resulting verbosity as compared to similarly factored Forth code just the cost of doing business when writing in Python compared to Forth, or am I missing some Python idioms?

asked Feb 3, 2014 at 9:43
\$\endgroup\$
2
  • 2
    \$\begingroup\$ Python functions return None by default, so unless you are planning on returning a value, don't include a return statement. \$\endgroup\$ Commented Feb 3, 2014 at 16:45
  • \$\begingroup\$ Don't put more than one statement on a single line. print(c,end=""); sys.stdout.flush(); sleep(0.05); print(chr(0x8),end=""); sys.stdout.flush() is not clear at all. \$\endgroup\$ Commented Feb 11, 2014 at 20:28

1 Answer 1

4
\$\begingroup\$

Repetitive code should be put in a loop.

Most programmers don't have the ASCII table memorized. Why not use literal characters instead?

Flush can be handled by print() itself. I don't believe you need to flush after backspacing.

The speed of the rotation can be made overridable with a trivial change.

from time import sleep 
def halftwirl(delay=0.05):
 """Twirls the cursor in place half-way i.e. | / - \."""
 for glyph in '|/-\\':
 print(glyph, end='', flush=True)
 sleep(delay) # sleep(sec) to keep it slow enough to see
 print('\b', end='') # backspace to keep it in place

To answer your questions:

  1. Performance is just not an issue here. The main slowdowns would be the deliberate sleep() call and I/O overhead.
  2. See the rewrite above.
answered Feb 3, 2014 at 10:06
\$\endgroup\$
1
  • 3
    \$\begingroup\$ The string constant would look nicer if written r'|/-\'. \$\endgroup\$ Commented Feb 3, 2014 at 18:47

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.