I'm trying to create a function that returns a 'pulse' every time it does something. The function must be passed as a callback if the person desires to receive the pulse. I'd like to print the pulses as new . character in the same line, so I did this:
import time
def do_something(do=None):
while True:
time.sleep(1)
if do: do('.')
def prtn(text):
print(text, end=' ')
do_something(prtn)
but the code gets stuck and won't print anything!
print is line buffered by default, and you are using print to print a value not terminated by a new line. So you will need to flush the buffer as a result in order to force it to output the value. See some ways of how to do this.
You call a function like a parameter...
import time
def prtn(text):
print(text, end=' ')
def do_something(do=False):
while True:
time.sleep(1)
if prtn: prtn('.')
do_something(do=True)
Related
I am trying to use time.sleep() to pause in between print statements.
import time
def test():
print("something", end="")
time.sleep(1)
print(" and ", end="")
time.sleep(1)
print("something")
When I use the end argument, the code waits before it starts to print. It should print, wait, print, wait, and print ("something, wait, and, wait, something"). However, when I use the end argument, it waits, and prints "wait something and something". This code works as I wanted it to without the end argumets.
Your output device is line-buffered and only flushes when a new line is output. Add flush=True as an additional parameter to print to force a flush to the output.
I have code that basically replicates Shell's tail -f function as the below:
def _read_log(logfile, logger):
def _generator(logfile):
with open(f'{logfile}', 'r') as file:
file.seek(0, os.SEEK_END)
while True:
line = file.readline()
if not regex_SSH.search(line):
sleep(1)
continue
ip = regex_IP.search(line).group()
logger.warning(f"Failed SSH Login for IP: {ip}")
yield ip
for line in _generator(logfile):
return line
What I would like to do is put this in its own separate thread and just have it running over and over. I thought the simple solution would be something like:
def main():
while True:
with ThreadPoolExecutor(max_workers=2) as executor:
executor.submit(_read_log)
executor.submit(some_other_function)
The problem I'm having is, nothing after executor.submit(_read_log) will run UNTIL that generator returns a value, which may take some time. Ideally I need the rest of my code to just keep chugging along even if the generator isn't returning a value. I'm a little stuck on this one, any assistance is greatly appreciated.
This question already has an answer here:
sys.stdout.write no longer prints on next row
(1 answer)
Closed 2 years ago.
I'm trying to print the following code in different lines but it always prints in the same line. Can anyone help please.
import time
import sys
def delay_print(s):
for c in s:
sys.stdout.write(c)
sys.stdout.flush()
time.sleep(0.05)
delay_print("Hi there hope everything is fine.")
time.sleep(2)
def delay_print(s):
for c in s:
sys.stdout.write(c)
sys.stdout.flush()
time.sleep(0.05)
delay_print("This is a mail.")
This is the output showing to me-
Hi there hope everything is fine.This is a mail.
How to print them like this-
Hi there hope everything is fine.
This is a mail.
Just add print("\n") after the for loop.
Functions are written when a particular task is to be done multiple times, declaring the same function is not needed just call it, and you are good to go!
Although you can put \n just in argument to function but better put it in function itself
def delay_print(s):
for c in s:
sys.stdout.write(c)
sys.stdout.flush()
time.sleep(0.05)
print("\n")
Also, on a side note, you dont need to re decalre the delay_print function
You can do the same thing as below without defining a function two times
import time
import sys
def delay_print(s):
for c in s:
sys.stdout.write(c)
sys.stdout.flush()
ime.sleep(0.05)
print("\n")
delay_print("Hi there hope everything is fine.")
time.sleep(2)
delay_print("This is a mail.")
You either want to use sys.stdout.writelines(), where you would pass a list of 1 value to, or you want to add in your delay_print() an end-of-line token as \r\n
Just add \n at the end of string in first delay_print() :
import time
import sys
def delay_print(s):
for c in s:
sys.stdout.write(c)
sys.stdout.flush()
time.sleep(0.05)
delay_print("Hi there hope everything is fine.\n") # like this .
time.sleep(2)
delay_print("This is a mail.")
I am making a text based game and I am trying to print this code one character at a time on each column.
'''###############
Let us begin...
###############'''
I can't figure out how to make it come out one column at a time.
Well, I still felt like answering this despite the vagueness of your question. Maybe this is what you are looking for, this prints one column at a time (one character per row):
import subprocess
import platform
from time import sleep
def clear_screen():
# thanks to: https://stackoverflow.com/a/23075152/2923937
if platform.system() == "Windows":
subprocess.Popen("cls", shell=True).communicate()
else:
print("\033c", end="")
# obviously you can create a function to convert your string into this
# list rather than doing it manually like I did, but that is another question :p.
views = ['#\nh\n#', '##\nhe\n##', '###\nhel\n###', '####\nhell\n####', '#####\nhello\n#####']
for view in views:
clear_screen()
print(view)
sleep(0.5)
If you are already doing print(c, end='') for each character in you string, just add flush=True to the call to print(). The sleep call will introduce enough delay so that you can see the characters print one at a time:
>>> import time
>>> s = '''###############
... Let us begin...
... ###############'''
>>> for c in s:
... print(c, end='', flush=True)
... time.sleep(0.1)
I want to make (for fun) python print out 'LOADING...' to console. The twist is that I want to print it out letter by letter with sleep time between them of 0.1 seconds (ish). So far I did this:
from time import sleep
print('L') ; sleep(0.1)
print('O') ; sleep(0.1)
print('A') ; sleep(0.1)
etc...
However that prints it to separate lines each.
Also I cant just type print('LOADING...') since it will print instantaneously, not letter by letter with sleep(0.1) in between.
The example is trivial but it raises a more general question: Is it possible to print multiple strings to one line with other function being executed in between the string prints?
In Python2, if you put a comma after the string, print does not add a new line. However, the output may be buffered, so to see the character printed slowly, you may also need to flush stdout:
from time import sleep
import sys
print 'L',
sys.stdout.flush()
sleep(0.1)
So to print some text slowly, you could use a for-loop like this:
from time import sleep
import sys
def print_slowly(text):
for c in text:
print c,
sys.stdout.flush()
sleep(0.5)
print_slowly('LOA')
In Python3, change
print c,
to
print(c, end='')
You can also simply try this
from time import sleep
loading = 'LOADING...'
for i in range(10):
print(loading[i], sep=' ', end=' ', flush=True); sleep(0.5)
from time import sleep
myList = ['Let this be the first line', 'Followed by a second line', 'and a third line']
for s in myList:
print(s) ; sleep(0.6)
If you've written a quite large program and want to add that feature, then overwrite the builtin function print
python_print = print
def print(txt):
text = str(txt)
for c in text:
python_print(c, end="", flush=True)
time.sleep(random.randint(2, 8)/100)
python_print()
This function ensures that
The output is flushed (no need of the sys module)
After one character was written, there is a delay of 0.02 to 0.08 seconds.
The actual behavior of the print function is kept (so you can make it print arrays and modules) - because of the str() call, though there are some exceptions.
What this function cannot do:
You can't call print like this anymore because it only takes one argument:
print("Hello", "World")
Feel free to add that feature or have a look at someone implemented that:
https://book.pythontips.com/en/latest/args_and_kwargs.html
Oh and if you haven't noticed yet - use python_print() if delayed text is inapropriate in some cases.
I wonder why python_print is not shallow-cloned. May anyone explain?
--
Someone implemented that :)
Someone has called my approach (I think especially the *args) cute and worked for at least 30 minutes to get something even better which is considerably larger (please, don't call it bloated though). I didn't test it, but it seems working well to my eyes.
So with that code you'll be able to use print like print("Hello", "World") again.
Credits to: #MarcinKonowalczyk =>
https://gist.github.com/MarcinKonowalczyk/48a08fe2492b88df184decf427fd2caf
Thank you for taking your time.
Now Run a Function While Loading
In order to run something (otherwise Loading would be useless anyway I guess) while it's printing, you can use the threading module.
So, without further ado, let's quickly get started.
import threading
def load():
# do I/O blocking stuff here
threading.Thread(target=load).start() # returns the thread object
# and runs start() to launch the function load() non-blocking.
print("LOADING...")
You may consider removing the random delay from my function which is untypical for a LOADING... screen.
If you don't need to wait until the LOADING... is done to close the program easily with ctrl-c, you can change the daemon attribute to True. Please note that, if the main thread finishes, your other thread will stop forcefully.
Here's an example to how you could to that:
loadingThread = Threading.thread(target=load)
loadingThread.daemon = True
loadingThread.start()
print("LOADING...")
loadingThread.join() # wait for the loadingThread to finish
With this, the program will exit just fine, however you may have to catch KeyboardInterrupt:
try:
loadingThread.join()
except KeyboardInterrupt:
# cleanup stuff here or just *pass*
finally: # optional, runs *always*
# cleanup stuff here
Updated to print all the letters on one line.
from time import sleep
import sys
sys.stdout.write ('L') ; sleep(0.1)
sys.stdout.write ('O') ; sleep(0.1)
sys.stdout.write ('A') ; sleep(0.1)
...
sys.stdout.write ('\n')
etc...
or even:
from time import sleep
import sys
output = 'LOA...'
for char in output:
sys.stdout.write ('%s' % char)
sleep (0.1)
sys.stdout.write ('\n')
To type a string one letter at a time all you've got to do is this:
import sys
import time
yourWords = "whatever you want to type letter by letter"
for char in yourWords:
sys.stdout.write(char)
time.sleep(0.1)
import time
import sys
def code(text, delay=0.07):
for c in text:
sys.stdout.write(c)
sys.stdout.flush()
time.sleep(delay)
print()
Instead of print type code