What does this print(' '*len(msg), end='') call do? - python

I am studying Python using a book. But there is an example code I don't understand:
from time import sleep
for i in range(100):
msg = '\rProgress %d%%' %(i+1)
print(' '*len(msg), end='') #I don't understand this statement.
print(msg, end='')
sleep(0.1)
Actually, I commented out that statement, I got the same result.
Why do I need that statement?

It is meant to print a series of spaces, to make sure the previous line is cleared.
In this specific case, that'll never happen, because the message printed will only grow longer (going from 0% to 99%). Moreover, the number of spaces is based on the new message, which would be too short if the previous message was longer.
So no, it is not needed here, you found an error in the book.

Related

Sleep function not working after program is saved [duplicate]

This question already has answers here:
How can I flush the output of the print function?
(13 answers)
Closed 1 year ago.
I am using a time.sleep function to have my strings printed letter by letter, and it works perfectly while running inside pycharm, yet when I save the program and run it directly, the function does not take effect
def welcome():
greeting = random.choice(open_msg)
for i in range(len(greeting)):
print(greeting[i], end='')
time.sleep(0.15)
This is an example of what the code looks like
By default, Python's output is line-buffered. Therefore it won't print anything until you print a linefeed. To avoid this behavior, flush the output after each letter. Since Python 3.3, print() has an argument to do this. (For older versions, you need to sys.stdout.flush() after each print().)
print(greeting[i], end='', flush=True)
You can cause Python not to buffer by invoking it with the -u flag or by setting the environment variable PYTHONUNBUFFERED to any value. But these affect all output. It's better to use flush where you need it and leave other output buffered, because buffered is faster.
By the way, don't use range() when iterating over a string. Iterate over the string directly and you get the characters.
for c in greeting:
print(c, end='', flush=True)
# etc.
Ides can take longer to execute, amplifying the time.sleep() function
Maybe lengthen the time in the argument of time.sleep()
It should be working. Perhaps you forgot one of your imports? If so, here is the code, it is written well.
import random
import time
open_msg = ['hello', 'finished', 'chicken']
def welcome():
greeting = random.choice(open_msg)
for i in range(len(greeting)):
print(greeting[i], end='' )
time.sleep(0.15)
welcome()
``

I can't seem to find what's wrong. It gives me no error message, but instead just ends the process without printing the wanted message

I can't seem to find what's wrong. It gives me no error message, but instead just ends the process without printing the wanted message
def choose_chracter_class():
character_class_option = raw_input()
return character_class_option
if character_class_option is str("mage") or str("Mage"):
print "Mage, sorcerers who wield mass amounts of magic energy to cause havoc among their opponents, summon entities, or protect themselves from harm."
print "Attack - 5"
print "Magic Atk - 30"
print "Defence - 10"
print "Magic Def - 15"
print "Speed - 10"
if chracter_class_option is str("warrior") or str("Warrior"):
print "Warrior"
else:
print character_class_option + " isn't an option"
choose_chracter_class()
I agree with the previous comment that one issue is the return on the second line preventing the remaining code from executing. I also agree with the previous comment that using the .lower() would probably be cleaner code then checking for both the situations of lowercase 'mage' and the first letter being capital 'Mage'. By using .lower() you don't need to check both situations of 'mage' and 'Mage' as no matter how it is typed even if it is typed like: 'mAgE' then the code would still work.
However, I have one idea to get the code to work in a similar way that you have it set up.
You could also try:
if character_class_option == "mage" or character_class_option == "Mage"
In addition, I don't think it is necessary use str() on something that is already a string. However, I can understand you may have done this in an attempt to debug.

Clear current line in STDOUT in python

So I made a program in python that asks a user for input repetitively. After a while, the previous commands start to build up, as so.
> Ping
Pong!
> Hello
Hey there!
>say whats up?
Whats up?
I made the commands up just to show examples
I want to add an animation that adds a ... to the end of a word, such as
i choose.
then clear the line then
i choose..
then clear the line then
i choose...
and so on, but I need to clear the screen in order for this to work and I want the history of the users commands and responses to sill be there. Is there any way using python or importing os to only remove one line instead of the entire screen? Thanks!
You are looking for the carriage return character, \r. When you print that character, the previous line will be cleared. For example:
import time
print('I choose',end='',flush=True)
time.sleep(1)
print('\rI choose.',end='',flush=True)
time.sleep(1)
print('\rI choose..',end='',flush=True)
time.sleep(1)
print('\rI choose...',end='',flush=True)
This is actually how people make the progress bar in command line.
You should be able to do this using normal ‘print’, just appending a comma to the end of the print statement:
from time import sleep
print ‘I choose.’,
sleep(0.5)
print ‘.’,
sleep(0.5)
print ‘.’
Edit: Added in sleeps to make the animation work more as expected.

How to print slowly with a while loop in python 2.7.9

I am trying to print each iteration of the following loop more slowly (so that the person seeing the image printed can actually make out what it is before it goes away too quickly). Any help is welcome. The following code doesn't seem to slow anything down, even when I change the integer to a different number. I don't understand why it's not working.
import time
while True:
print """There are normally 55 lines of strings here, but for readability sake I have deleted them and inserted this text instead."""
time.sleep(5)
Because the call to sleep is outside the while loop, you'll run all the prints, and only then sleep the program.
Indent the call to sleep to include it in your loop.
wrong indentation it should be
import time
while True:
print """There are normally 55 lines of strings here, but for readability sake I have deleted them and inserted this text instead."""
time.sleep(5)

Problems refreshing stdout line using print with python

I've been trying to print out the progress of a for loop in python2.7 using the following code:
for i in range(100):
if float(i) % 10.0 == 0:
print i, "\r",
The behaviour I'm after is the refreshing of the same line on std out rather than writing to a new line every time.
EDIT 1:
Testing in my console (Xfce Terminal 0.4.8), I actually don't get any output regardless of whether I include the if statement or not.
Why is there no output?
I originally said the behaviour of the stdout changed depending on the if statement being there or not because I simplified the code that produced the problem to its most simple form (only to produce the above mentioned effect). My apologies.
EDIT 2:
Thanks to senderle, this is solved. If you miss out the sleep() command, the prints and carriage return happen so quickly you can't see them.
EDIT 3:
One last thing. If you don't catch for the final number in range(100), i.e. 99, the number is cleared off the screen.
EDIT 4:
Note the comma after print i in senderle's answer.
I have found that using sys.stdout is a more system-independent way of doing this, for varions reasons having to do with the way print works. But you have to flush the buffer explicitly, so I put it in a function.
def carriage_return():
sys.stdout.write('\r')
sys.stdout.flush()
This is kind of a WAG. Let me know if it helps.
I tried this and it works for me. The time.sleep is just for dramatization.
import sys, time
def carriage_return():
sys.stdout.write('\r')
sys.stdout.flush()
for i in range(100):
if i % 10 == 0:
print i,
carriage_return()
time.sleep(1)
Finally, I have seen people do this as well. Using terminal control codes like this seems right in some ways, but it also seems more brittle to me. This works for me with the above code as well (on OS X).
def carriage_return():
if sys.platform.lower().startswith('win'):
print '\r'
else:
print chr(27) + '[A'
Testing your code as is, and just including a :colon: at the end of the first line, works just fine with Py2.7 32bit, Windows7 64-bit.
Do you have any out writes to stdout in your if or for block that could be causing the new-lines to be written out ?

Categories