Why doesn't the second python function run? Infinite loop
Question:
I have to make two separate functions, one that prints ‘Ha’ after every 1 second, and another one that prints ‘Ho’ after every 2 seconds.
But b()
is greyed out, and it won’t run.
import time
def a():
while True:
time.sleep(1)
print('Ha')
def b():
while True:
time.sleep(2)
print('Ho')
a()
b()
Why is the second function not running?
Edit: I have to have 2 separate functions that can both run infinitely.
Answers:
The b() function is never called because a() never returns. Here’s a simple approach that achieves what you are looking for:
import time
count = 0
while True:
time.sleep(1)
print("Ha")
if count % 2 :
print("Ho")
count += 1
If you made your program multi-threaded, you could run a() in one thread and b() in another thread and your approach would work.
Here’s a version of your program with multi-thread – which allows both your a() and b() functions to run somewhat simultaneously:
import time
from threading import Thread
class ThreadA(Thread):
def a():
while True:
time.sleep(1)
print('Ha')
def run(self):
ThreadA.a()
class ThreadB(Thread):
def b():
while True:
time.sleep(2)
print('Ho')
def run(self):
ThreadB.b()
ThreadA().start()
ThreadB().start()
Edit: Here’s a simpler multi-threaded version which allows you to specify the function to execute when you start the thread (I probably should look through the threading module for this feature – it seems like it should be in there):
import time
from threading import Thread
class ThreadAB(Thread):
def run(self):
self.func()
def start(self,func):
self.func = func
super().start()
def a():
while True:
time.sleep(1)
print('Ha')
def b():
while True:
time.sleep(2)
print('Ho')
ThreadAB().start(a)
ThreadAB().start(b)
Here’s an absolutely horrible solution that runs both functions in different processes without threads or classes:
#!/usr/bin/env python
import time
import sys
import os
def a():
while True:
time.sleep(1)
print('Ha')
def b():
while True:
time.sleep(2)
print('Ho')
if len(sys.argv) > 1:
eval( sys.argv[1] )
else:
os.system(f"{sys.argv[0]} 'a()' &")
os.system(f"{sys.argv[0]} 'b()' &")
For the above solution to work, I made my program executable and ran it from the command line like this:
command
The results were somewhat awful. I kicked off two programs running at the same time in the background. One of the programs printed Ha and the other Ho. They both were running in the background so I had to use the following command to kill them:
ps -ef | grep command | awk '{print $2}' | xargs kill
Edit: And finally, here’s an asyncio approach (my first time writing something like this):
import asyncio
async def a():
while True:
print('Ha(1)')
await asyncio.sleep(1)
async def b():
while True:
print('Ho(2)')
await asyncio.sleep(2)
async def main():
taskA = loop.create_task (a())
taskB = loop.create_task(b())
await asyncio.wait([taskA,taskB])
if __name__ == "__main__":
try:
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
except :
pass
Credit for the above code: https://www.velotio.com/engineering-blog/async-features-in-python
I have to make two separate functions, one that prints ‘Ha’ after every 1 second, and another one that prints ‘Ho’ after every 2 seconds.
But b()
is greyed out, and it won’t run.
import time
def a():
while True:
time.sleep(1)
print('Ha')
def b():
while True:
time.sleep(2)
print('Ho')
a()
b()
Why is the second function not running?
Edit: I have to have 2 separate functions that can both run infinitely.
The b() function is never called because a() never returns. Here’s a simple approach that achieves what you are looking for:
import time
count = 0
while True:
time.sleep(1)
print("Ha")
if count % 2 :
print("Ho")
count += 1
If you made your program multi-threaded, you could run a() in one thread and b() in another thread and your approach would work.
Here’s a version of your program with multi-thread – which allows both your a() and b() functions to run somewhat simultaneously:
import time
from threading import Thread
class ThreadA(Thread):
def a():
while True:
time.sleep(1)
print('Ha')
def run(self):
ThreadA.a()
class ThreadB(Thread):
def b():
while True:
time.sleep(2)
print('Ho')
def run(self):
ThreadB.b()
ThreadA().start()
ThreadB().start()
Edit: Here’s a simpler multi-threaded version which allows you to specify the function to execute when you start the thread (I probably should look through the threading module for this feature – it seems like it should be in there):
import time
from threading import Thread
class ThreadAB(Thread):
def run(self):
self.func()
def start(self,func):
self.func = func
super().start()
def a():
while True:
time.sleep(1)
print('Ha')
def b():
while True:
time.sleep(2)
print('Ho')
ThreadAB().start(a)
ThreadAB().start(b)
Here’s an absolutely horrible solution that runs both functions in different processes without threads or classes:
#!/usr/bin/env python
import time
import sys
import os
def a():
while True:
time.sleep(1)
print('Ha')
def b():
while True:
time.sleep(2)
print('Ho')
if len(sys.argv) > 1:
eval( sys.argv[1] )
else:
os.system(f"{sys.argv[0]} 'a()' &")
os.system(f"{sys.argv[0]} 'b()' &")
For the above solution to work, I made my program executable and ran it from the command line like this:
command
The results were somewhat awful. I kicked off two programs running at the same time in the background. One of the programs printed Ha and the other Ho. They both were running in the background so I had to use the following command to kill them:
ps -ef | grep command | awk '{print $2}' | xargs kill
Edit: And finally, here’s an asyncio approach (my first time writing something like this):
import asyncio
async def a():
while True:
print('Ha(1)')
await asyncio.sleep(1)
async def b():
while True:
print('Ho(2)')
await asyncio.sleep(2)
async def main():
taskA = loop.create_task (a())
taskB = loop.create_task(b())
await asyncio.wait([taskA,taskB])
if __name__ == "__main__":
try:
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
except :
pass
Credit for the above code: https://www.velotio.com/engineering-blog/async-features-in-python