Running a function in Python if a user chooses it (EasyGui) - python

I'm using EasyGui to allow a user to select multiple options. Each option is a function which they can run if they select it. I'm trying to use dictionaries as suggested in other threads but I'm having trouble implementing it (Module object is not callable error). Is there something I'm missing?
from easygui import *
import emdtest1
import emdtest2
import emdtest3
EMDTestsDict = {"emdtest1":emdtest1,
"emdtest2":emdtest2,
"emdtest3":emdtest3}
def main():
test_list = UserSelect()
for i in range(len(test_list)):
if test_list[i] in EMDTestsDict.keys():
EMDTestsDict[test_list[i]]()
def UserSelect():
message = "Which EMD tests would you like to run?"
title = "EMD Test Selector"
tests = ["emdtest1",
"emdtest2",
"emdtest3"]
selected_master = multchoicebox(message, title, tests)
return selected_master
if __name__ == '__main__':
main()

You're putting modules into the dict, when you want to put functions in it. What you're doing is the equivalent of saying
import os
os()
Which, of course, makes no sense. If emdtest1, emdtest2, and emdtest3 are .py files with functions in them, you want:
from emdtest1 import function_name
Where function_name is the name of your function.

You need to import the functions rather than the module ... for example , if you have a file called emdtest1 with a defined function emdtest1, you'd use:
from emdtest1 import emdtest1

Related

How to monkeypatch a python library class method?

I am trying to modify a better_profanity library to include an additional argument to get_replacement_for_swear_word function. To do so I first import the necessary parts of the library and test its functionality before:
from better_profanity import profanity, Profanity
text = "Nice c0ck"
censored = profanity.censor(text)
print(censored)
Now I get the source code of the class method, modify it and execute it to __main___:
from inspect import getsource
new_hide_swear_words = getsource(profanity._hide_swear_words).replace(
'get_replacement_for_swear_word(censor_char)', 'get_replacement_for_swear_word(censor_char, cur_word)').replace(
'ALLOWED_CHARACTERS', 'self.ALLOWED_CHARACTERS'
)
# fixing the indent
new_hide_swear_words = '\n'.join(i[4:] for i in new_hide_swear_words.split('\n'))
exec(new_hide_swear_words)
Now I replace this function inside the class:
profanity._hide_swear_words = _hide_swear_words.__get__(profanity, Profanity)
Note that I swap ALLOWED_CHARACTERS for self.ALLOWED_CHARACTERS. This is because the author of the library has imported ALLOWED_CHARACTERS in the same file where the class is defined, so when I swap the function and try to run the first piece of code again, it sais that this variable is not defined. It just so happens that it is stored in self as well, but there is no such luck with several other imported modules. Any ideas how to tackle this?
Here is the class definition on github.
When you run exec(new_hide_swear_words), you define the function _hide_swear_words in your current module (that's why you can access it later with just _hide_swear_words).
That however means, that the function lives fully in your module, so when you call it indirectly with profanity.censor(some_text) it will run the function inside this module and look for all dependent global symbols in your module.
That's why it can't access the variable ALLOWED_CHARACTERS or the function any_next_words_form_swear_words. They are defined in the profanity module, but not in your module where you run the exec.
One way to solve this, would be to just import all symbols into your module.
from inspect import getsource
from better_profanity import Profanity, profanity
from better_profanity.constants import ALLOWED_CHARACTERS
from better_profanity.utils import *
new_hide_swear_words = getsource(profanity._hide_swear_words)
new_hide_swear_words = "\n".join(i[4:] for i in new_hide_swear_words.split("\n"))
exec(new_hide_swear_words)
profanity._hide_swear_words = _hide_swear_words.__get__(profanity, Profanity)
text = "Nice c0ck"
censored = profanity.censor(text)
print(censored)
Another way would be to execute the function in the profanity module itself (then all the symbols are already defined).
However that also has a little overhead. E.g. you have to import the module and pass it to the exec function, and afterwards you need to extract the function from the module (as it will be defined in that module).
from importlib import import_module
from inspect import getsource
from better_profanity import Profanity, profanity
new_hide_swear_words = getsource(profanity._hide_swear_words)
# fixing the indent
new_hide_swear_words = "\n".join(i[4:] for i in new_hide_swear_words.split("\n"))
profanity_module = import_module(Profanity.__module__)
exec(new_hide_swear_words, vars(profanity_module))
profanity._hide_swear_words = profanity_module._hide_swear_words.__get__(
profanity, Profanity
)
text = "Nice c0ck"
censored = profanity.censor(text)
print(censored)
profanity_module = import_module(Profanity.__module__) is the same thing as import better_profanity.better_profanity as profanity_module.

Can't import functions/modules

I'm simply trying to import a function from another script. But despite import running successfully, the functions never enter my local environment.
The paths and files look like this:
project/__main__.py
project/script_a.py
from setup import script_b
x = ABC() # NameError: name 'ABC' is not defined
print(x)
project/setup/__init__.py
project/setup/script_b.py
def ABC():
return "ABC"
I've done this before and the documentation (officials and on here) is quite straightforward but I cannot grasp what I am failing to understand. Is the function running but never entering my environment?
I also tried using...
if __name__ == '__main__':
def ABC():
return "ABC"
...as script_b.
Import the functions inside the module:
from setup.script_b import ABC
Or call the function on the modules name like said in the comments
x = script_b.ABC()

How do I import all functions from a package in python?

I have a directory as such:
python_scripts/
test.py
simupy/
__init__.py
info.py
blk.py
'blk.py' and 'info.py are modules that contains several functions, one of which is the function 'blk_func(para)'.
Within '__init__.py' I have included the following code:
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
file_lst = os.listdir(dir_path)
filename_lst = list(filter(lambda x: x[-3:]=='.py', file_lst))
filename_lst = list(map(lambda x: x[:-3], filename_lst))
filename_lst.remove('__init__')
__all__ = filename_lst.copy()
I would like to access the function 'blk_func(para)', as well as all other functions inside the package, within 'test.py'. Thus I import the package by putting the following line of code in 'test.py':
from simupy import*
However, inorder to use the function, I still have to do the following:
value = blk.blk_func(val_param)
How do I import the package simupy, such that I can directly access the function in 'test.py' by just calling the function name? i.e.
value = blk_func(val_para)
Pretty easy
__init__.py:
from simupy.blk import *
from simupy.info import *
Btw, just my two cents but it looks like you want to import your package's functions in __init__.py but perform actions in __main__.py.
Like
__init__.py:
from simupy.blk import *
from simupy.info import *
__main__.py:
from simupy import *
# your code
dir_path = ....
It's the most pythonic way to do. After that you will be able to:
Run your script as a proper Python module: python -m simupy
Use your module as library: import simupy; print(simupy.bar())
Import only a specific package / function: from simupy.info import bar.
For me it's part of the beauty of Python..

Python import class from other files

I have three files under the same directory, namely, main.py, Newtester.py, and fileUtility.py. In Newtester.py there is a class named Function. In main.py, there are the following codes:
from file.py import *
...
def main():
...
funcs = parseFuncSpec(funcInputFile)
parseFuncSpec is defined in fileUtilities.py as:
some code to import Newtester.py
def parseFuncSpec(fName):
curFunc = function(funcName, numTest, [], score)
Regardless of what I put in import Newtester.py, I always get an error saying "Function" (the class defined in the file "Newtester.py") is not defined. Following Python: How to import other Python files, I have attempted
import Newtester
__import__("Newtester")
exec("Newtester.py")
exec("Newtester")
import importlib
importlib.__import__("Newtester")
os.system("Newtester.py")
But none of them seemed to work. Any advice is appreciated. See https://github.com/r2dong/unitTesting if you are interested in seeing the complete files.
It's because you are not using it correctly
well when you use import statement like below only Newstester file is imported
import Newtester
hence instead of using parseFuncSpec() directly you have to use it as Newtester.parseFuncSpec()
or to use parseFuncSpec() directly you need to use below import statement:
from Newtester import parseFuncSpec

Python Creating and Importing Modules

I wrote functions that are applyRules(ch), processString(Oldstr) and named it lsystems.py
And I put
import lsystems
def main():
inst = applyRules("F")
print(inst)
main()
and saved it as mainfunctioni
However, when I try to run mainfunctioni, it says 'applyRules' is not defined.
Doesn't it work because I put import lsystems?
What should I do to work my mainfunctioni through lsystems?
You have to call it with module.function() format. So in this case, it should be called like as follows:
inst = lsystems.applyRules("F")
You have to access all the methods from your module with the same format. For processString(Oldstr), it should be similar.
test_string = lsystems.processString("Somestring")
When you import a module using import <module> syntax, you need to access the module's contents through its namespace, like so:
import lsystems
def main():
inst = lsystems.applyRules("F")
print(inst)
main()
Alternatively, you can directly import the function from the module:
from lsystems import applyRules
def main():
inst = applyRules("F")
print(inst)
main()

Categories

Resources