python autopy problems/confusion - python

so im trying to make a bot script that when a certain hex color is on a certain pixel it will execute some code to move the mouse,click etc. and i have it to where it takes a screenshot every 1 second to the same png file and updates the png file's pic. i have the hex color for the pixel cords print to the console so i can see if its updating or not. it never updates it just stays the same. ive tried writing this script many ways and sadly i only have one version to show you but hopefully you will understand what i was trying to accomplish. im on python 2.7 btw. thank you all for your time!!!!
import autopy
from time import sleep
color_grabber = hex(autopy.bitmap.Bitmap.open("screen1.png").get_color(292,115))
def color_checker():
global color_grabber
color_grabber = color_grabber
return
def mouse_move_click():
autopy.mouse.smooth_move(433,320)
autopy.mouse.click()
def screen_grab():
autopy.bitmap.capture_screen().save("screen1.png")
def the_ifs(mouse_move_click):
if color_checker == "0xffcb05":
mouse_move_click()
while 1==1:
sleep(1)
screen_grab()
color_checker()
the_ifs(mouse_move_click)
print color_grabber

from autopy.mouse import LEFT_BUTTON
autopy.mouse.click(LEFT_BUTTON)
autopy.mouse.toggle(True, LEFT_BUTTON)
autopy.mouse.toggle(False, LEFT_BUTTON)
I see the need to do this in other people's code, but I don't understand why want to use the up and down after the click.In fact when I test on Windows 7, click is effective, but is not very correct, feel more like the down to my operation

I believe your problem is how you're using color_grabber. Saying color_grabber = color_grabber does nothing. What's happening in your code is that when you run it, after the imports, you define the value of color_grabber to be the color in your image. Then your while loop executes and in that loop you call color_checker. This function brings in the variable color_grabber from the global namespace and then you set that variable equal to itself. You're not re-executing the command you used to define color_grabber in the first place. You're just storing the color value back into itself so clearly its not going to change.
You also have a problem in how you're calling your mouse_move_click function. You don't want to pass in the function name, as that isn't really necessary. However, you also performed the check color_checker == "0xffcb05" which was comparing your function (the function itself, not the returned value) to the hex code. That doesn't do you any good. You want to compare the color. The solution is to pass the color into the_ifs and use that color to compare to the hex code. I should note though that you don't need to make the_ifs into its own function. Just put that if statement in your while loop. I left it how you had it though.
What you want is something like this.
import autopy
from time import sleep
def color_checker():
color_grabber = hex(autopy.bitmap.Bitmap.open("screen1.png").get_color(292,115))
return color_grabber
def mouse_move_click():
autopy.mouse.smooth_move(433,320)
autopy.mouse.click()
def screen_grab():
autopy.bitmap.capture_screen().save("screen1.png")
def the_ifs(color):
if color == "0xffcb05":
mouse_move_click()
while 1==1:
sleep(1)
screen_grab()
color = color_checker()
the_ifs(color)
print color
Note that I have not run this code myself so I can't guarantee it works, but I believe it should.

Related

How to stop functions from giving errors when using variables not defined in the function?

I am creating several experiments in python and have various functions which will be common across these experiments. I thus wanted to create a script only containing these functions which I could import at the beginning of the experimental script to avoid half of the script being taken up with 'generic setup lines'.
So far, I have created the functions and the script and can import them and use them. For example, in the following, I have a function which shows a blank screen which takes the duration I want (e.g., 4 seconds) and displays it on the window defined in the experimental script.
import functions
win = visual.Window([1440,900], color=[-1,-1,-1], fullscr=True)
dur = 4
functions.blank_screen(duration=dur)
This all works fine but in the script containing the functions, there are several 'errors' the function uses the variable 'win' which is not defined in the function:
def blank_screen(duration):
blank = TextStim(win, text='')
blank.draw()
win.flip()
But when I run the experimental script, as it is defined in the script, it all works. How can I get around this? I have this problem with several functions as a large majority uses variables which are defined in the experimental script and not in the functions. As I say, it all works but just annoys me that the script is covered in 'errors'!
I'd be greatly appreciative of any help, thank you!
You can pass on the win you want blanked out as an argument to the blank_screen function:
import functions
win = visual.Window([1440,900], color=[-1,-1,-1], fullscr=True)
dur = 4
functions.blank_screen(duration=dur, win=win)
and
def blank_screen(duration, win):
blank = TextStim(win, text='')
blank.draw()
win.flip()

call function inside argument of a function in python

I am starting with python, and I am trying to understand the sample code that Phidget website give to me (I bought a Phidget Bridge 4 input where I have plug on 4 gauge cell). For my project I need to use python but not much use to it.
To read only one channel, sol only one gauge cell with my Phidget bridge, the website give me this code.
from Phidget22.Phidget import *
from Phidget22.Devices.VoltageRatioInput import *
import time
def onVoltageRatioChange(self, voltageRatio):
print("VoltageRatio: " + str(voltageRatio))
def main():
voltageRatioInput0 = VoltageRatioInput()
voltageRatioInput0.setOnVoltageRatioChangeHandler(onVoltageRatioChange)
voltageRatioInput0.openWaitForAttachment(5000)
time.sleep(5)
voltageRatioInput0.close()
main()
There is the function def onVoltageRatioChange(self, voltageRatio): which takes 2 arguments, self and voltageRatio, and this function is used inside setOnVoltageRatioChangeHandler(onVoltageRatioChange) with no argument. What I mean, it's that I do not get why we give as an argument onVoltageChange (which is normally a function) to the function setOnVoltageRatioChangeHandler...
It someone could explain it to me, it could help me to build my own code... at least try..
thank you
Phidget22 knows how to detect a voltage ratio change, but it doesn't know what you want to do with it: maybe you want to sound an alarm. maybe you want to send an email with the new ratio. maybe you just want to print it to the screen.
So it uses setOnVoltageRatioChangeHandler to ask you what you would like to do once it detects this voltage change, saying "hey, if you'll give me a function that takes a voltage ratio, I'll call it when I detect a change" then you can do:
setOnVoltageRatioChangeHandler(soundTheAlarm)
or
setOnVoltageRatioChangeHandler(sendAnEmail)
or:
setOnVoltageRatioChangeHandler(printToScreen)
The supplied onVoltageRatioChange will just print the new value to the screen.
Generally, passing a function as an argument is a great way to give flexibility in the way events are handled. It's basically saying "I know how to detect a certain situation or get a certain value. You let me know what you want me to do once I do"

Repeating a function with another function

for an assignment we needed to make a function that flipped a coin and another to flip it 100 times. I was able to make a function that flipped a coin, but got stuck when trying to call it a 100 times with another function. This is what I have right now:
import random
def TC():
face = random.randint(0,1)
if face == 1:
return "head"
else:
return "tail"
print TC()
def ply(flips):
for i in range(flips):
return TC()
print ply(100)
When I run it it just says 'none.' Please tell me where I am going wrong. Thank You!
Just to start, your method naming is very bad. I doubt this is how your professor is teaching you to name methods and variables. It's ugly, against Python standards and hard to read I suggest you take some time and read PEP 8 it's how python was intended to be written.
So instead of TC you should use something like flip_coin and instead of ply use something like play_coin_flip or even simply play.
Next I don't know if I'm stepping outside of what you have learned but instead of using randon.randint you can use randon.choice.
And finally, as others have said, when you return you quit any other execution in a function and return whatever variable you retrun in that statement thus nullifying any other iterations of the loop you're performing. I suggest something like the below as a better program with corrections applied to make it function as intended.
from random import choice
faces = ['head', 'tail']
def flip_coin():
face = choice(faces)
return face
def play_coin_flip(flips = 1):
for i in range(flips):
print(flip_coin)
if __name__ == "__main__":
play_coin_flip(100)

Python GTK get selected value from the treeview

I am working on a mini GUI project , I am currently struggling to figure out how to get selected value from the list and then return that value to the main function so that I can use that value in somewhere else . Can someone help me please !!!!
####
self.device_list_store = gtk.ListStore(str,str,str,str,str)
for device in self.get_dev_list():
self.device_list_store.append(list(device))
device_list_treeview = gtk.TreeView(self.device_list_store)
selected_row = device_list_treeview.get_selection()
selected_row.connect("changed",self.item_selected)
####
def item_selected(self,selection):
model,row = selection.get_selected()
if row is not None:
selected_device = model[row][0]
at the moment ,the item_selected function is not returning anything , I want to return selected_device back to the main function so I can use it in other functions as well .
EDIT: I've edited code above to remove formatting errors #jcoppens
As you can see in the documentation, the item_selected function is called with one parameter, tree_selection. But if you define the function inside a class, it requires the self parameter too, which is normally added automatically. In your (confusing) example, there is no class defined, so I suspect the problem is your program which is incomplete.
Also, I suspect you don't want device_list_treeview = gtk.T... in the for loop:
for device in self.get_dev_list():
self.device_list_store.append(list(device))
device_list_treeview = gtk.TreeView(self.device_list_store)
And I suspect you want selected_device = mod... indented below the if:
if row is not None:
selected_device = model[row][0]
Please convert your example in a complete program, and formatted correctly.
BTW: item_selected is not a good name for the signal handler. It is also called if the item is unselected (which is why the signal is called 'changed')!
And important: Even though you should first read the basic Python tutorials and Gtk tutorials, you should then consider using lazka's excellent reference for all the Python APIs. There's a link on the page to download it completely and have it at hand in your computer.

Python Global Variable Not Working

I have an extremely long program for a Canasta game that I am writing, in it there is a variable that ends the turn of the player if it equals a certain value. However, the turn repeats itself.
I have read many different articles and posts on forums like this one, but none of these seem to work. I even have a debug system to print the value of the variable before the if statement, and the variable is the right value, but the if statement doesn't see the same value.
I can't give the entire code, as it is extremely long, but I can give the sections that use this variable. I am using Python 2.7.2 and cannot make files separate from the main file to import.
The first line of the program is:
endTurn=1
The following function is called when conditions to win the game are met, but I have not been able to test that this works because of the bug.
def winGame(player):
global endTurn
gameWinner=player
gameWinner["score"]+=100
endTurn=0
The following function is called when a move is made. The variable decide is a raw_input() variable.
def move(player,decide):
global endTurn
theMove=decide.lower()
#if player says to end turn
if theMove=="end":
#until player discards something
discarded=0
while not discarded:
displayHand(player)
#ask player for discard
discard=int(raw_input(" Enter the list number of the card you wish to discard:"))-1
#if discard ID is in player's hand length
if not discard<0 and not discard>len(player["hand"])-1:
#add card to discard pile and remove from hand
discardPile.append(player["hand"][discard])
del(player["hand"][discard])
discarded=1
debug("Before changing, endTurn is %s"%str(endTurn))
endTurn = 0
debug("After changing, endTurn is %s"%str(endTurn))
if theMove=="new book":
newBook(player)
if theMove=="add to book":
addBook(player)
Here is where the turn should be ended. turn(thePlayer) repeats the function. The debug statement shows the correct value, 0, but the if still reads a 1. The function this is in also has the global endTurn at the top.
debug("If ending turn, endTurn of %s should be 0."%str(endTurn))
if endTurn==1:
turn(thePlayer)
Any help is greatly appreciated!
EDIT: The code is available at http://labs.codecademy.com/CV9z#:workspace. I ask that anyone viewing the code does not modify it, so that other people can see the true code.
I fixed the bug. I removed the endTurn variable and instead made the function that ends the turn just do the turn of the next player. It also simplified my code a bit.
I am wondering though, is using this method of running a function inside of itself over and over and over again (without leaving) rather messy or maybe slowing down my program?
EDIT: I now realize that this answer does not exactly help with anyone else who is stuck with global variables...
The previous answer I posted was just wrong, as it was based on a misinterpretation of the namespace docs as I had read them (Thanks to TheifMaster for pointing out my error), so this is a SEVERELY EDITED ANSWER:
The problem is in the while loop that I was able to read when the link to the entire code was posted after the erroneous answer I gave earlier.
while gameWinner==0:
endTurn=1
turn(player1)
if not gameWinner==0:
endTurn=1
turn(player2)
The game can never get to player two in this loop until gameWinner!=0.
I added the entire code to my sandbox and changed it to:
while gameWinner==0:
endTurn=1
turn(player1)
if gameWinner==0: #if player1 did not win yet
endTurn=1
turn(player2)
However, the game is still buggy... No one can win! gameWinner is not changed globally by the winGame() function until you add it to the global statement as I have shown here.
def winGame(player):
global endTurn, gameWinner
gameWinner=player
gameWinner["score"]+=100
debug("gameWinner == " + str(gameWinner))
endTurn=0

Categories

Resources