1

Suppose I have a function like this:


import random  
def randomfunc():
    x = random.randint(0,10)
    # some code here which generates a name/text randomly and stores it in a .txt file locally/cloud
    if x%2 == 0:
        y=input("Enter your name:") # I need to enter that name/text exact here
        print("Your name is ",y)
    else:
        print("You got an odd number")

Now, whenever I run this function then I want it to detect if it is asking for any input or not. If it's asking for input then enter the input else do nothing.

Remember I can't change anything inside the function.

I tried this:


import builtins
from unittest.mock import patch
with patch('builtins.input') as input_mock:
    input_mock.side_effect = [
        'My Name',
    ]
    print(input('Enter your name:'))

But the problem here is that the input is predetermined before the execution of the input statement. In my case, my input value will be decided while the execution of randomfunc() as my input value is dynamic/it changes with time.

Also, when using wexpect module, it gives me OSError: [WinError 6] The handle is invalid.

Please suggest me some solution.

  • FWIW, this difficulty is one example of why programmers are advised to separate I/O from business logic. I.e., just don't write functions like this; make the program work by calling `input` in a place that is **dedicated to asking for input**, and pass that information to other functions as an argument. – Karl Knechtel Jan 16 '23 at 07:40

2 Answers2

1

I believe that is what you want

def randomfunc():
    x = random.randint(0, 10)
    if x % 2 == 0:
        y = input("Enter your name:")
        print("Your name is ", y)
    else:
        print("You got an odd number")


def better_randomfunc(user_input):
    with mock.patch('builtins.input') as MockClass:
        MockClass.return_value = user_input
        randomfunc()

This will replace every input() in randomfunc with your own one that'll return user_input. So if there's no input function it's going to do nothing like you asked. To use this just call the better_randomfunc

better_randomfunc("My name")

And expect double space, if you want to get rid of that do print("Your name is", y) instead of print("Your name is ", y)

Edit: I improved it a little bit so that you can modify it based on prompt

import random
from unittest import mock


def randomfunc():
    x = random.randint(0, 10)
    if x % 2 == 0:
        y = input("Enter your name: ")
        print("Your name is", y)
    else:
        print("You got an odd number")


def better_input(prompt, user_input):
    print(prompt + user_input)
    return user_input


def better_randomfunc(user_input):
    with mock.patch('builtins.input') as MockClass:
        MockClass.side_effect = lambda prompt: better_input(prompt, user_input)
        randomfunc()


better_randomfunc("My name")
WingedSeal
  • 439
  • 1
  • 4
  • 12
0

You can replace the builtin input function

import random

input_values = [1,2,3,4]
input_iterator = iter(input_values)

def randomfunc():
    x = random.randint(0,10)
    if x%2 == 0:
        y=input("Enter your name:")
        print("Your name is ",y)
    else:
        print("You got an odd number")


def custom_input(v):
    global input_iterator
    print('custom input called')
    # input(*args, **kwargs)
    return next(input_iterator)

setattr(__builtins__, 'input', custom_input)


while(True):
    try:
        randomfunc()
    except StopIteration:
        print('done')
        break
You got an odd number
custom input called
Your name is  1
custom input called
Your name is  2
custom input called
Your name is  3
You got an odd number
You got an odd number
You got an odd number
custom input called
Your name is  4
You got an odd number
custom input called
done
Epsi95
  • 8,832
  • 1
  • 16
  • 34