3

I'm running a python 2.7 program using Terminal, on a Mac. If I open up Terminal and run the program, it executes differently from when I run the program a second time, in the same Terminal window. What could possibly cause a problem like this?


Below is the code I'm using. The line print bg("grey_50") prints nothing on the first program execution, but it correctly prints a grey line on the second execution. On BOTH executions, the for function operates the same, and correctly. Why does the grey line only print the second time I run the program?

uses_color = "True"

if uses_color == "True":
    from colored import fg, bg

if uses_color == "True":
    print bg("grey_50")
    for i in range(44):
        print bg("grey_100")

As a side note, there is also some code between the second and third stanzas that works the same, and correctly, every time I run the function.

Additionally, please observe that both the line print bg("grey_50") and print bg("grey_100") use the colored module, but only the latter of those two works consistently.


Link to colored: https://github.com/dslackw/colored

Colin Hancey
  • 219
  • 2
  • 8
  • 2
    Does the code as you have pasted it here work for you repeatably? There may be side effects (to either the bg function or uses_color) caused by the code you have omitted. – Simon Bowly Dec 25 '17 at 22:20
  • 1
    Is there a reason you're using a string `"True"` instead of the native Python boolean `True`? I don't know if it's causing this issue, but it could be kinda problematic. – Chris Riebschlager Dec 25 '17 at 22:23
  • Simon: Using ONLY the code I have pasted above, I experience the exact issue as described above. Chris: I use strings as a personal preference. I tried switching them to boolean, and the issue persists. – Colin Hancey Dec 25 '17 at 22:23
  • 1
    Can you show how exactly you are executing this script? – poke Dec 25 '17 at 22:32
  • poke, dawg: I'm not exactly sure what you mean, but in Terminal I use cd to change the directory to the folder containing the script, then I type "python doodles.py" where "doodles.py" is the name of the script, written in emacs. Everything works perfectly, except this issue with the grey line, and only on the first execution. – Colin Hancey Dec 25 '17 at 22:35
  • What do you mean by 'run the program'? Does it have a shebang? Are you invoking Python first? Have you made it executable? – dawg Dec 25 '17 at 22:35
  • Could you show a screenshot from the output in your terminal? Also, maybe reduce the range to just `4` (instead of `44`) to show both executions next to another. – poke Dec 25 '17 at 22:47
  • Glenn: I use this function to print lines of a solid color throughout the program, and they all work like this. It's only this particular line that messes up. – Colin Hancey Dec 25 '17 at 23:16
  • @poke: just so you know: you will only see a number of blank lines in the default background color. OP's construction only works on scrolling. – Jongware Dec 25 '17 at 23:17
  • 1
    @usr2564301 Well, that would have been something one could have told from a screenshot, hence me asking ;) But good job on figuring it out! – poke Dec 25 '17 at 23:59

1 Answers1

5

This has nothing to do with your program or repeated runs. The problem lies in the behavior of your terminal when scrolling. Only when scrolling, the terminal uses the current background color to fill the entire line.

On a first run, with the current edit prompt high enough, you will see that no color at all is printed. On next runs, the display scrolls and the terminal checks with what color to clear – the current active background color. My default terminal background is not pure white (the grey_100 in your code) so I don't see anything different in the first run.

If you literally want to print an entire line in the background color, interrogate your terminal width and print a line of spaces.

from colored import fg, bg, attr
import os

# from https://stackoverflow.com/questions/566746/how-to-get-linux-console-window-width-in-python
rows, columns = os.popen('stty size', 'r').read().split()

columns = int(columns)

print bg("red")+(columns * ' ')
for i in range(10):
    print bg("yellow")+(' ' * columns)
print attr('reset')
Jongware
  • 22,200
  • 8
  • 54
  • 100
  • Yeah, this solves my problem! But, about your explanation, shouldn't the terminal "scroll" whenever a new line is printed? It sounds like the grey line never gets printed, because the background gets set to grey, but a new line is never printed, and so there is no line to fill with the grey background. If this were true, just printing a line with print "" would work, but it doesn't. – Colin Hancey Dec 25 '17 at 23:30
  • 1
    @ColinHancey: if you don't print *any text at all*, the background color never appears. Only if the terminal *must* scroll, then the bottom line gets cleared in the current background color. Printing a new line does not automatically mean the screen will scroll, only if it happens when the cursor is at the bottom. – Jongware Dec 25 '17 at 23:34
  • 2
    Alright, makes sense! Have to get the terminal to scroll to clear a line in the current background setting. You have a great eye for catching that! I did find a simpler solution, which is just to add a series of blank prints before printing the grey line. Maybe this only works nicely for my purposes, though. – Colin Hancey Dec 25 '17 at 23:50