Calling a function from another file within an if-Python 3.x - python-3.x

I've found resources on here but they're pertaining to locally embedded functions. I have one file called "test" and another called "main". I want test to contain all of my logic while main will contain a complete list of functions which each correlate with a health insurance policy. There are hundreds of policies so it would become quite tedious to write an if statement in "test" for each one each time. I'd like to write as few lines as possible to call a function based off of what a value states. Something like:
insurance = input()
The end result would not be an input but for testing/learning purposes it is. The input would always correlate with an insurance policy exactly if it exists. So on "tests" I currently have:
from inspolicy.main import bcbs, uhc, medicare
print('What is the insurance?(bcbs, uhc, medicare)')
insurance = input()
if insurance.lower() == 'bcbs':
bcbs()
elif insurance.lower() == 'uhc':
uhc()
elif insurance.lower() == 'medicare':
medicare()
else:
print('This policy can not be found in the database. Please set aside.')
With "main" including:
def bcbs():
print('This is BCBS')
def uhc():
print('This is UHC')
def medicare():
print('This is Medicare')
So is there a way to have the input (i.e. insurance) be what is referenced against to call the function from "main"?
Thank you in advance for your time!

The best approach to this is to use a dictionary to map between the name of your insurance policies and the function that deals with them. This could be a hand-built dict in one of your modules, or you could simply use the namespace of the main module (which is implemented using a dictionary):
# in test
import types
import inspolicy.main # import the module itself, rather than just the functions
insurance = input('What is the insurance?(bcbs, uhc, medicare)')
func = getattr(inspolicy.main, insurance, None)
if isinstance(func, types.FunctionType):
func()
else:
print('This policy can not be found in the database. Please set aside.')

Let's consider this is your main.py
def uhc():
print("This is UHC")
It is possible to do something like that in test.py:
import main
def unknown_function():
print('This policy can not be found in the database. Please set aside.')
insurance = input()
try:
insurance_function = getattr(main, insurance.lower())
except AttributeError:
insurance_function = unknown_function
insurance_function()
Then, if you type "uhc" as your input, you will get the uhc function from main.py and call it.

Related

Python: command line, sys.argv, "if __name__ == '__main__' "

I have a moderate amount of experience using Python in Jupyter but am pretty clueless about how to use the command line. I have this prompt for a homework assignment -- I understand how the algorithms work, but I don't know how to format everything so it works from the command line in the way that is specified.
The prompt:
Question 1: 80 points
Input: a text file that specifies a travel problem (see travel-input.txt
for the format) and a search algorithm
(more details are below).
python map.py [file] [search] should read
the travel problem from “file” and run the “search” algorithm to find
a solution. It will print the solution and its cost.
search is one of
[DFTS, DFGS, BFTS, BFGS, UCTS, UCGS, GBFTS, GBFGS, ASTS, ASGS]
Here is the template I was given:
from search import ... # TODO import the necessary classes and methods
import sys
if __name__ == '__main__':
input_file = sys.argv[1]
search_algo_str = sys.argv[2]
# TODO implement
goal_node = ... # TODO call the appropriate search function with appropriate parameters
# Do not change the code below.
if goal_node is not None:
print("Solution path", goal_node.solution())
print("Solution cost", goal_node.path_cost)
else:
print("No solution was found.")
So as far as python map.py [file] [search] goes, 'file' refers to travel-input.txt and 'search' refers to one of DFTS, DFGS, BFTS,... etc - a user-specified choice. My questions:
Where do I put my search functions? Should they all just be back-to-back in the same block of code?
How do I get the command line to recognize each function from its four or five-letter code? Is it just the name of the function? If I call it just using those letters, how can the functions receive input?
Do I need to reference the input file anywhere in my code?
Does it matter where I save my files in order for them to be accessible from the command line - .py files, travel-input.txt, etc? I've tried accessing them from the command line, with no success.
Thanks for the help!
The function definitions go before the if __name__ == "__main__" block. To select the correct function you can put them in a dict and use the four-letter abbreviations as keys, i.e.
def dfts_search(...):
...
def dfgs_search(...):
....
...
if __name__ == "__main__":
input_file = sys.argv[1]
search_algo_str = sys.argv[2]
search_dict = {"DFTS": dfts_search, "DFGS": dfgs_search, ...}
try:
func = search_dict[search_algo_str]
result = func(...)
except KeyError:
print(f'{search_algo_str} is an unknown search algorithm')
Not sure what you mean by reference, but input_file already refers to the input file. You will need to write a function to read the file and process the contents.
The location of the files shouldn't matter too much. Putting everything in the same directory is probably easiest. In the command window, just cd to the directory where the files are located and run the script as described in the assignment.

Name activation for my assistant. How could I create a function to execute a block of code when one name as input is said?

I have been working on a virtual assistant project and wanted a voice activation system so that it isn't always listening to what I am saying unless I say its name.
This is the code for the speech recognition. and I am trying to create a function so that when my voice inputs "name" of the assistant, it activates. Once it does what I ask it once, it should go back to sleep unless I summon again.
def takeCommand():
r = sr.Recognizer()
with sr.Microphone() as source:
print("Listening...")
r.pause_threshold = 1
audio = r.listen(source)
try:
print("Recognizing...")
query = r.recognize_google(audio, language='en-us')
print("User said: {query}\n")
except Exception as e:
(My exception handler. I did this to minimize the code)
return query
if __name__ == '__main__':
clear = lambda: os.system('cls')
# This Function will clean any
# command before execution of this python file
clear()
wishMe()
usrname()
voice_activation()
while True:
query = takeCommand().lower()
# All the commands said by user will be
# stored here in 'query' and will be
# converted to lower case for easily
# recognition of command
And after that, there are a list of commands like for example...
elif 'open youtube' in query:
(Assistant speaks)
webbrowser.open("youtube.com")
I have tried making a new function like
def voice_activation
but I didn't know where to put it and how to structure it
There was a suggestion to create a class variable but I don't exactly know where I could place it in my program because of how its structured. Again, thank you for helping me with this program.
Instead of making a bunch of standalone functions, make them class methods instead. Then you can make a class variable voice_activated = False. Make a class method voice_activation like you said, then in that, an if statement. If 'assistant name' in query, voice activated = true. Then in all of your query functions you could encompass them in if voice activated= True, or something to that effect?

Pytest user input simulation

I am brand new to pytest and trying to work my way through it.
I currently am programming a small CLI game which will require multiple user inputs in a row and I cannot figure out how I can do that.
I read a bunch of solutions but did not manage to make it work.
Here is my code:
class Player:
def __init__(self):
self.set_player_name()
self.set_player_funds()
def set_player_name(self):
self.name = str(input("Player, what's you name?\n"))
def set_player_funds(self):
self.funds = int(input("How much money do you want?\n"))
I simply want to automate the user input for those two requests.
(ie: a test that would input "Bob" and test: assert player.name=="Bob"
Can someone help out with that?
Thank you!
Quite elegant way to test inputs is to mock input text by using monkeypatch fixture. To handle multiple inputs can be used lambda statement and iterator object.
def test_set_player_name(monkeypatch):
# provided inputs
name = 'Tranberd'
funds = 100
# creating iterator object
answers = iter([name, str(funds)])
# using lambda statement for mocking
monkeypatch.setattr('builtins.input', lambda name: next(answers))
player = Player()
assert player.name == name
assert player.funds == funds
monkeypatch on docs.pytest.org.
Iterator object on wiki.python.org.

Get a user's keyboard input that was requested by another function

I am using a python package for database managing. The provided class has a method delete() that deletes a record from the database. Before deleting, it asks a user to verify the operation from a console, e.g. Proceed? [yes, No]:
My function needs to perform other actions depending on whether a user chose to delete a record. Can I get user's input requested by the function from the package?
Toy example:
def ModuleFunc():
while True:
a=input('Proceed? [yes, No]:')
if a in ['yes','No']:
#Perform some actions behind a hood
return
This function will wait for one of the two responses and return None once it gets either. After calling this function, can I determine the User's response (without modifying this function)? I think a modification of the Package's source code is not a good idea in general.
Why not just patch the class at runtime? Say you had a file ./lib/db.py defining a class DB like this:
class DB:
def __init__(self):
pass
def confirm(self, msg):
a=input(msg + ' [Y, N]:')
if a == 'Y':
return True
return False
def delete(self):
if self.confirm('Delete?'):
print ('Deleted!')
return
Then in main.py you could do:
from lib.db import DB
def newDelete(self):
if self.confirm('Delete?'):
print('Do some more stuff!')
print('Deleted!')
return
DB.delete = newDelete
test = DB()
test.delete()
See it working here
I would save key events to somewhere(file or memory) with something like Keylogger. Then, you will be able to reuse last one.
However, if you can modify module package 📦 and redistribute, it would be easier.
Return
To
Return a

Ibpy: how to capture data returned from reqAccountSummary

I'm using ibapi from interactive brokers and I got stuck on how to capture the returned data, generally. For example, according to api docs, when I request reqAccountSummary(), the method delivered the data via accountSummary(). But their example only print the data. I've tried capturing the data or assign it to a variable, but no where in their docs shows how to do this. I've also google search and only find register() and registerAll() but that is from ib.opt which isn't in the latest working ibapi package.
Here is my code. Could you show me how to modify accountSummary() to capture the data?
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.common import *
class TestApp(EWrapper,EClient):
def __init__(self):
EClient.__init__(self,self)
# request account data:
def my_reqAccountSummary1(self, reqId:int, groupName:str, tags:str):
self.reqAccountSummary(reqId, "All", "TotalCashValue")
# The received data is passed to accountSummary()
def accountSummary(self, reqId: int, account: str, tag: str, value: str, currency: str):
super().accountSummary(reqId, account, tag, value, currency)
print("Acct# Summary. ReqId>:", reqId, "Acct:", account, "Tag: ", tag, "Value:", value, "Currency:", currency)
return value #This is my attempt which doesn't work
def main():
app = TestApp()
app.connect("127.0.0.1",7497,clientId=0)
app.my_reqAccountSummary1(8003, "All", "TotalCashValue") #"This works, but the data is print to screen. I don't know how to assign the received TotalCashValue to a variable"
# myTotalCashValue=app.my_reqAccountSummary1(8003, "All", "TotalCashValue") #"My attempt doesn't work"
# more code to stop trading if myTotalCashValue is low
app.run()
if __name__=="__main__":
main()
You cannot do this in the main function, since app.run listens to responses from the TWS. Once you have set up all the callbacks as you correctly did, the main function will be looping forever in app.run.
You have to put your code directly into the accountSummary function. This is how these kind of programs work, you put your logic directly into
the callback functions. You can always assign self.myTotalCashValue = value to make it available to other parts of your class, or even to another thread.
-- OR --
You run app.run in a thread and wait for the value to return, e.g.
add self._myTotalCashValue = value to accountSummary, import threading and time and then add something like this in main:
t = threading.Thread(target=app.run)
t.daemon = True
t.start()
while not hasattr(app,"_myTotalCashValue"):
time.sleep(1)
print(app._myTotalCashValue)
As usual with threads, you have to be a bit careful with shared memory between app and main.

Resources