Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does using print() too much cause it to fail?

TL;DR:

The print() result is not updating in a Windows Console. Executes fine in IDLE. Program is executing even though Windows Console is not updating.

Background

I have a file, test.py that contains:

Edit: Included the conditions that I used to see if the Console was updating. Eventually the series of X values never prints again in Console and the Console never scrolls back up (as it normally does when output is being generated at the bottom).

count = 0
while True:
    print ("True")
    count += 1
    if count == 10:
            print ("XXXXXXXXX")
            count = 0

When I run this in cmd.exe it obviously prints a very large number of True.

However, after about 25 seconds of running, it stops printing any more, though the program is still running and can be seen in the Task Manager.

I have a program with some progress indicators that end up stay at say 50% even though they are moving well beyond 50% simply because print() is not showing in the Console output.

Edit: The true use case problem.

The above code was just a test file to see if printing in Console stopped in all programs, not the one I was running. In practice, my program prints to Console and looks like:

line [10] >> Progress 05%

Where line [10] isn't real but I merely typed here to show you that print() sends to that line in the Console window. As my program continues it increments:

line [10] >> Progress 06%
line [10] >> Progress 11%
.
.
.
line [10] >> Progress 50%

Each time line [10] is overwritten. I use ANSI escape characters and colorama to move the Console cursor accordingly:

print('\x1b[1000D\x1b[1A')

This moves the cursor 1000 columns left and 1 row up (so the start of the previous line).

Something is happening where the print("Progress " + prog + "%") is not showing up anymore in Console because eventually the next bit of Python gets executed:

line [11] >> Program Complete...

I verified the resultants which get put into a folder. So the program continued to run while the Console did not update.

Edit: Here is the script running the updates to the stdout.

def check_queue(q, dates, dct):
    out = 0
    height = 0

    # print the initial columns and rows of output
    # each cell has a unique id 
    # so they are stored in a dictionary
    # then I convert to list to print by subscripting
    for x in range(0, len(list(dct.values())), 3):
        print("\t\t".join(list(dct.values())[x:x+3]))
        height +=1 # to determine where the top is for cursor

    while True:
        if out != (len(dates) * 2):
            try:
                status = q.get_nowait()
                dct[status[1]] = status[2]
                print('\x1b[1000D\x1b[' + str(height + 1) + 'A')

                # since there was a message that means a value was updated
                for x in range(0, len(list(dct.values())), 3):
                    print("\t\t".join(list(dct.values())[x:x+3]))

                if status[0] == 'S' or 'C' or 'F':
                    out += 1
            except queue.Empty:
                pass
    else:
        break

In short, I pass a message to the queue from a thread. I then update a dictionary that holds unique cell IDs. I update the value, move the cursor in Console to the upper left position of the printed list, and print over it.

Question:

When using stdout, is there a limit to how many times you can print to it in a period of time?

like image 268
datta Avatar asked Aug 08 '17 17:08

datta


2 Answers

That may well be an illusion (maybe because there's a maximum limit of lines in the console and new ones just replace the first ones then).

There's definetly no limit how much you can print. You could verify this with something that changes each iteration, for example a loop that counts the number of iterations:

import itertools
for i in itertools.count():
    print(i, "True")
like image 153
MSeifert Avatar answered Oct 23 '22 03:10

MSeifert


I cannot reproduce the problem in Windows 10 using 64-bit Python 3.6.2 and colorama 0.3.9. Here's the simple example that I tested:

import colorama
colorama.init()

def test(M=10, N=1000):
    for x in range(M):
        print('spam')
    for n in range(N):
        print('\x1b[1000D\x1b[' + str(M + 1) + 'A')
        for m in range(M):
            print('spam', m, n)

Each pass successfully overwrites the previous lines. Here's the final output from looping N (1000) times:

>>> test()
spam 0 999
spam 1 999
spam 2 999
spam 3 999
spam 4 999
spam 5 999
spam 6 999
spam 7 999
spam 8 999
spam 9 999

If this example fails for you, please update your question and include the versions of Windows, Python, and colorama that you're testing.

like image 28
Eryk Sun Avatar answered Oct 23 '22 02:10

Eryk Sun