3
\$\begingroup\$

This program opens a file and prints the text out to the terminal 1 character at a time and at a predetermined speed using time.sleep()

Simple and maybe, if you think like me, pretty cool..

GitHub

from time import sleep
import sys

BLINK = 0.2
chars_in_line = 50

def open_file(fn):
    with open(fn, "r") as f:
        for line in f:
            if line:
                yield line

def type_out_text_to_line(text, end="", sep="", line_chars=None, blink=0.2):
    if not text:
        return ""

    c = line_chars
    for i, j in enumerate(text):
        sys.stdout.flush()
        sleep(blink)
        print(j, end=end, sep=sep)
        if line_chars:
            if i + 1 == c:
                print()
                c += line_chars
    return ""


print("\n\tSTART PRINTING\n")

for text in open_file('example.txt'):
    if len(text) > 1:
        print(type_out_text_to_line(text, line_chars=chars_in_line, blink=BLINK, sep=""))

print("\n\tEND PRINTING\n")
\$\endgroup\$
1

1 Answer 1

4
\$\begingroup\$

I would recommend just using the built in functionality of print to do the flushing. Though I am an advocate for breaking things out into classes and functions, you should use built in functionality when you can.

Making code complex for no reason results in two things:

1) More bugs.
2) More programmers who want to wring your neck down the road because they have to maintain or fix your software.

So you can simplify your code like this:

from time import sleep

BLINK = 0.2

print("\n\tSTART PRINTING\n")

with open('example.txt') as f:
    for line in f:
        for char in line:
            print(char, flush=True, end='')
            sleep(BLINK)

print("\n\tEND PRINTING\n")

If you want to make this into a function (to make it easier to import/export) then I would do following:

from time import sleep

def time_print_file(filename, print_rate, **print_kwargs):
    """
    INPUT:
        filename: The path to the file to be printing
        print_rate: The delay used to print each character
        print_kwargs: keyword arguments accepted by pythons
           print statement. (Except `end` and `flush`)
    """
    print_kwargs.pop('flush', None) # We don't allow the flush print-keyword
    print_kwargs.pop('end', None) # We don't allow the end print-keyword
    with open(filename) as f:
        for line in f:
            for char in line:
                print(char, flush=True, end='', **print_kwargs)
                sleep(print_rate)


if __name__ == '__main__':
    print("\n\tSTART PRINTING\n")
    time_print_file(filename='example.txt', print_rate=0.2)
    print("\n\tEND PRINTING\n")
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Reading the whole file into memory with f.readlines might not be the best idea (although letting the program type out a file larger than memory is probably not going to happen). Instead just iterate over the file with for line in f. It also includes the newline characters, just like f.readlines. \$\endgroup\$
    – Graipher
    Jul 16, 2019 at 16:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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