The code is an implementation of looping text (similar to a circular buffer - wraps around when it reaches the edge of the defined bounds) with directional control.

The code is functional and works as intended, but I'm curious if there is anyway to improve the code even if it is only a small improvement (e.g. less garbage produced per loop cycle as a micro-optimisation, etc).

# cleaned up and improved prototype code for looping text scroll.
# added direction from the original code.

from sys import stdout
from time import sleep

global_shifted_text_array = []
global_text_length = 0


def set_text(text):
    global global_shifted_text_array
    global global_text_length

    global_shifted_text_array = pad_text(text)
    global_text_length = len(global_shifted_text_array)

def pad_text(text, padding = 5):
    text += ' ' * padding
    return list(text)

def shift_text(direction):
    global global_shifted_text_array
    range = xrange(global_text_length - 1, -1, -1) if direction == DIRECTION_LEFT_TO_RIGHT else xrange(global_text_length)

    # by the time the zero element is set in the for loop.
    # it is set to the last element (which is empty)
    # so we have to account for this by correcting for it.
    if direction == DIRECTION_RIGHT_TO_LEFT:
        first_element = global_shifted_text_array[0]

    for i in range:
        global_shifted_text_array[i] = global_shifted_text_array[((i + direction) % global_text_length)]
        # print 'global_shifted_text_array[{}] = global_shifted_text_array[{}]'.format(i, ((i + direction) % global_text_length))

    if direction == DIRECTION_RIGHT_TO_LEFT:
        global_shifted_text_array[global_text_length - 1] = first_element

def update_loop(direction = DIRECTION_LEFT_TO_RIGHT, frequency = 0.1):
    while 1:

set_text('Beautiful Lie')

When I try it, it doesn't really work unless I add stdout.flush() after each stdout.write().

The padding isn't controllable, as neither set_text() nor update_loop() accepts a padding parameter.

In my opinion, it should print the original text before performing the first shift.

Global variables are bad. In this case, I'd eliminate them altogether by simplifying the code. Take advantage of itertools.cycle() and Python's support for negative indexes. I wouldn't bother with converting the string to a list and back to a string again.

DIRECTION_LEFT_TO_RIGHT is a bit verbose. I suggest SCROLL_RIGHT instead. "Frequency" sounds like it should go faster as the number increases: 10 Hz is faster than 1 Hz. I suggest period as the name for the delay.

from itertools import cycle
from sys import stdout
from time import sleep


def animate_text(text, scroll=SCROLL_RIGHT, period=0.5, padding=5):
    text += ' ' * padding
    for offset in cycle(xrange(0, scroll * len(text), scroll)):
        stdout.write('\r' + text[offset:] + text[:offset])

animate_text('Beautiful Lie')
| improve this answer | |
  • \$\begingroup\$ I intentionally avoiding using itertools as I plan on reimplementing this in C#, so I have avoided anything "pythonic". Thanks for the suggestions on naming I've taken that advice! By the way I think that SCROLL_LEFT = +1 is verbose since the plus isn't needed. \$\endgroup\$ – Yaseen Ssenyonjo Sep 29 '18 at 22:31
  • \$\begingroup\$ If you're interested in C#, ask a follow-up question in C#. Don't let C#'s limitations force you to do silly things in Python. \$\endgroup\$ – 200_success Sep 29 '18 at 22:32
  • \$\begingroup\$ Haha, I guess it is silly to implement it this way in Python but I have a preference for doing all prototyping in Python. Is there any equivalent of itertools.cycle() in C#? \$\endgroup\$ – Yaseen Ssenyonjo Sep 29 '18 at 22:34
  • \$\begingroup\$ If you have a C# question, then post a C# question. \$\endgroup\$ – 200_success Sep 29 '18 at 22:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.