Access method from different package in Python - python-3.x

I am trying to automate android game. I have so many methods so I break my code in 3 parts.
main, functions and collectors.
I have a method in functions which is:
def search_image(image, confidence=.6, click=True):
location = pyautogui.locateCenterOnScreen(image, confidence=confidence)
if location is not None:
if click:
pyautogui.click(location)
return location
else:
return False
But I cant access it in collectors, like this:
from functions import*
def collect_product():
if search_image(r'Resources\NewOrderAvailable.png') is not False:
search_image(r'Resources\NewOrderAvailable2.png')
for item in range(0, 6):
search_image(r'Resources\Collect.png', confidence=.8)
search_image(r'Resources\Back.png')
search_image(r'Resources\CloseOrderMenu.png')
else:
return False
I got NameError: name 'search_image' is not defined. I need to duplicate that method to make it work. I was wondering what went wrong and how to fix it?

Your function is not an instance of the class. You need to add a self keyword to make it accessible outside.
def search_image(self, image, confidence=.6, click=True):
location = pyautogui.locateCenterOnScreen(image, confidence=confidence)
if location is not None:
if click:
pyautogui.click(location)
return location
else:
return False

Try
import functions
functions.search_image('...')

Related

Why print function doesn't work in method: get_details() and None is returned for print(x.increment_odometer)?

class Car:
def __init__(self,make,model,year):
self.make=make
self.model=model
self.year=year
self.odometer_reading=0
def get_details(self): #SELF allows access of attributes and methods of a class
details=print((f'The make is: {self.make}, the model is: {self.model}, & the year is: {self.year}\n'))
#return details without print function works? i.w. details=rest of the line without print + return details (next line)
def read_odometer(self): #reading the value (default)
print(f'\nReading: {self.odometer_reading}')
def update_odometer(self,mileage):
if mileage>=self.odometer_reading:
print('\nReading has been changed')
self.odometer_reading=mileage
else:
print('\nCan, not change ')
def increment_odometer(self,miles):
self.odometer_reading+=miles
x.get_details() #trying to modify print(x.get_details()) which does work. Why does print need to be supplied here?
#incrementing the odometer
print(x.increment_odometer(50)) #why is this none?
I am learning classes and am confused about some aspects:
Why is "return details" line needed for method get_details()? Normally a simple function call having def f(): print('a') works, hence the confusion.
print(x.increment_odometer(50)) is None. Perhaps a function return needed in increment_odometer() method?
Confusing points having been commented in the code. Please englighten me.
Sincerely.

Trying to figure out how to pass variables from one class to another in python while calling a class from a dictionary

So I am getting used to working with OOP in python, it has been a bumpy road but so far things seem to be working. I have, however hit a snag and i cannot seem to figure this out. here is the premise.
I call a class and pass 2 variables to it, a report and location. From there, I need to take the location variable, pass it to a database and get a list of filters it is supposed to run through, and this is done through a dictionary call. Finally, once that dictionary call happens, i need to take that report and run it through the filters. here is the code i have.
class Filters(object):
def __init__ (self, report, location):
self.report = report
self.location = location
def get_location(self):
return self.location
def run(self):
cursor = con.cursor()
filters = cursor.execute(filterqry).fetchall()
for i in filters:
f = ReportFilters.fd.get(i[0])
f.run()
cursor.close()
class Filter1(Filters):
def __init__(self):
self.f1 = None
''' here is where i tried super() and Filters.__init__.() etc.... but couldn't make it work'''
def run(self):
'''Here is where i want to run the filters but as of now i am trying to print out the
location and the report to see if it gets the variables.'''
print(Filters.get_location())
class ReportFilters(Filters):
fd = {
'filter_1': Filter1(),
'filter_2': Filter2(),
'filter_3': Filter3()
}
My errors come from the dictionary call, as when i tried to call it as it is asking for the report and location variables.
Hope this is clear enough for you to help out with, as always it is duly appreciated.
DamnGroundHog
The call to its parent class should be defined inside the init function and you should pass the arguments 'self', 'report' and 'location' into init() and Filters.init() call to parent class so that it can find those variables.
If the error is in the Filters1 class object, when you try to use run method and you do not see a location or a report variable passed in from parent class, that is because you haven't defined them when you instantiated those object in ReportFilters.fd
It should be:
class ReportFilters(Filters):
fd = {
'filter_1': Filter1(report1, location1),
'filter_2': Filter2(report2, location2),
'filter_3': Filter3(report3, location3)
}
class Filter1(Filters):
def __init__(self, report, location):
Filters.__init__(self, report, location)
self.f1 = None
def run(self):
print(self.get_location())

Global variable in imported Python Class

It my first try to realize a "little bit bigger" project in python. Thus I want to structure the whole project using different python files. I also need some global variables. The following example works, if I put everything in one file. As soon as I split in two files it doesn't work anymore. What's an elegant way to solve the problem:
class MyClass:
def call(self):
print("In Methode call")
self.check()
def check(self):
global a
if a:
print("a ist True")
a = False
else:
print("a ist False")
a = True
def methode3(self):
print("In methode 3")
if __name__=="__main__":
a=True
instanz = MyClass()
instanz.methode3()
instanz.call()
instanz.check()
This script itself works fine.
If I call it now from the following second script, I get the error that 'a'is not defined. Call of instanz.methode3() works of course.
import test
a = True;
instanz = test.MyClass();
instanz.methode3()
instanz.call()
The following check,
if __name__=="__main__":
Is only called from when the file is run by itself as opposed to being imported. Declaring the a outside this if should work as intended.
Also, to access the new variable a, use test.a.

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

Passing a Function as a Parameter for a Class, eventually turning it into a method

Sorry if the title is confusing. I'm writing a minimalist game engine, and trying to define a class called "Area" where if the player enters the area, a function defined by the user happens. For example, one could create an instance
Area(location,function) that would fire function on the player when the player enters location (for the sake of simplicity, let it be a point or something).
Note: in pseudo-python
# in init.py
...
def function(player):
kill player
deathZone = Area(location,function)
--------------------------------------
# in player.update()
...
for area on screen:
if player in area:
Area.function(player)
The point of this is that the developer (aka me) can use any function they choose for the area. Is there anyway to do this, or should I try a better approach?
Sure, this kind of thing is certainly possible. In python, everything is an object, even a function. So you can pass around a function reference as a variable. For example try the following code:
import math
def rectangle(a, b):
return a*b
def circle(radius):
return math.pi * radius**2
class FunctionRunner(object):
def __init__(self):
self.userFunction = None
self.userParams = None
def setUserFunction(self, func, *params):
self.userFunction = func
self.userParams = params
def runFunction(self):
return self.userFunction(*self.userParams)
if __name__ == '__main__':
functionRunner = FunctionRunner()
functionRunner.setUserFunction(rectangle, 6, 7)
print(functionRunner.runFunction())
functionRunner.setUserFunction(circle, 42)
print(functionRunner.runFunction())
Here you have two functions that are defined for an area, and a class called FunctionRunner which can run any function with any number of input arguments. In the main program, notice that you need only pass the reference to the function name, and any input arguments needed to the setUserFunction method. This kind of thing will allow you to execute arbitrary code on the fly.
Alternatively, you could also replace a method on your class with a reference to another function (which is what you are asking), though this seems less safe to me. But it is certainly possible. For example you could have a class like this:
class FunctionRunner2(object):
def __init__(self):
pass
def setUserFunction(self, func):
self.theFunction = func
def theFunction(self, *params):
pass
And then do this:
if __name__ == '__main__':
functionRunner2 = FunctionRunner2()
functionRunner2.setUserFunction(rectangle)
print(functionRunner2.theFunction(6,7))
functionRunner2.setUserFunction(circle)
print(functionRunner2.theFunction(42))

Resources