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.

Asked By: paparonnie

||

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

Answered By: Mark
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.