Python - Code ignores `if`-statement? - python

I just got into Python (Jython) coding a few hours ago and I'm trying to automate Kik messenger (using an Android emulator) using Sikuli IDE.
I am trying to make a region observer that scans for changes, if a change is made, it will check if any commands are found. I am not really sure what I'm doing, but this is the code I got with some help all around the web and documentations:
cmdScanLoc = Region(Region(65,762,167,59))
def cmdHelp():
type("Help")
type(Key.ENTER)
cmdScanLoc.stopObserver()
def cmdPing():
type("Pong.")
type(Key.ENTER)
cmdScanLoc.stopObserver()
def changeDetected(event):
print("Change")
if cmdScanLoc.exists("1440090739688.png"):
cmdHelp()
elif cmdScanLoc.exists("1440090725124.png"):
cmdPing()
else:
print("No Command Found")
def startObserver():
cmdScanLoc.onChange(50,changeDetected)
cmdScanLoc.observe(10,background=False)
Settings.ObserveScanRate = 10
startObserver()
Here is the log, after typing !ping:
Change
!help
[log] TYPE "Help"
[log] TYPE "#ENTER."
It seems to go to cmdHelp(), even though I typed !ping. How is that possible? It just completely ignores the if-statement.
And here is an image of the region I'm scanning:
http://i.imgur.com/QAP9OnV.png
And an image of the images I'm scanning for:
http://i.imgur.com/wXxphQN.png (code in this image is no longer accurate as you can see)
I would greatly appreciate it if someone could guide me in the right direction with this "command scanner" where if a certain command is detected, the appropiate function is called.
Thanks a lot in advance and sorry if this is a really nooby question, I've just been trying for hours and hours, looking up documentation of Sikuli and Python and I just can't get it to work...

It's much smarter and much faster to do this kind of thing with the region observer than with an if-statement. Example code:
def cmd1(event):
print("Command One")
event.cmdRegion.stopObserver()
waitCmdAppear()
def cmd2(event):
print("Command Two")
event.cmdRegion.stopObserver()
waitCmdAppear()
def cmd3(event):
print("Command Three")
event.cmdRegion.stopObserver()
waitCmdAppear()
def waitCmdAppear():
cmdRegion.onAppear(Pattern("1.png").exact(), cmd1)
cmdRegion.onAppear(Pattern("2.png").exact(), cmd2)
cmdRegion.onAppear(Pattern("3.png").exact(), cmd3)
cmdRegion.observe(FOREVER)
waitCmdAppear()
Things to not forget:
The (event) part when defining a function that's going to be called by the region observer.
Stopping the Observer in the event, even if you are going to need it again. Just restart it.
In the onAppear, (region.onAppear([PS], [handler])) type the handler (ex. cmd3) not the function (ex. cmd3())
I hope this will help other people. :)

Related

Maya Python: Undo becomes unavailable after using undoInfo()

I've created a tool in Maya that takes values from currently selected objects, does some modifications to them and gives them back.I also have a simple gui window(made in QtDesigner if it makes sense),which has a QSlider and I pass values by dragging this slider. So, everything was working fine and I thought that it's completely ready for using but some problems with undo appeared. So, below in the init method I do this
super(winMain, self).__init__()
loader = QtUiTools.QUiLoader()
self.ui = loader.load(ui_path, self)
self.slider_released = self.ui.slider.sliderReleased
I have more code written in here it's just not connected to this. Below is the actionCaller() function where I call the action() function(this just does some math and generates values that should be passed to objects).
def actionCaller(self, some_value):
cmds.undoInfo(openChunk=True, infinity=True)
while not self.slider_released:
continue
else:
self.action(some_value)
cmds.undoInfo(closeChunk=True)
So I want to pass sliders value(some_value) only when it's released and therefor I added cmds.undoInfo() method for undoing the whole process as a one undo. Everything works fine while I use my program, only when I try to undo actions I've done before executing my code Maya gives this error:
// Error: line 1: Undo is temporarily unavailable. Try exiting the current tool.
I think that maya somehow gets in the while loop that I wrote above and undo queue becomes unavailable. Maybe I'm wrong idk. Can someone please tell me what the problem could be in here?
Thanks in advance :)
Comments section is not comfortable for posting code so I'm doing it here.
#musicamante using sliderReleased as a condition was actually a bad idea, so doing what you suggested helped. I modified the code a little bit and now it looks like this and everything works as expected:
self.ui.slider.sliderReleased.connect(self.actionCaller)
and
def actionCaller(self, slider_value):
cmds.undoInfo(openChunk=True, infinity=True)
try:
while not True:
continue
else:
self.action(slider_value)
finally:
cmds.undoInfo(closeChunk=True)
Thanks for your help:)

How would I create something similar to the Minecraft Server Console in python3

I'm messing around with some networking stuff and I wanted the server to be able to issue commands, namely a "stop" command. The idea was to create something similar to the minecraft server console. The issue is that when using threading, there are a few problems with just using print() and input()
Image of the Minecraft Server Console incase you dont know what I mean.
I tried to research a few things but found nothing good. I was trying to learn curses but I'm not sure how helpful it would be. I decided before I go any further I would ask on stack overflow before wasting any more time with research (I've been trying to figure this out for 2-3 days now)
Is there any simple way to do this?
I decided to go thru with learning basic curses.
I was able to make this test code and modify for my application
import curses,time
import curses.textpad
def main(screen):
h,w = screen.getmaxyx()
window = curses.newwin(h-2,w,0,0)
window.scrollok(True)
InputContainer = curses.newwin(1,w,h-1,0)
inputWindow = curses.newwin(1,w-2,h-1,2)
inputField = curses.textpad.Textbox(inputWindow,insert_mode=True)
InputContainer.addstr('> ')
window.addstr(0,0,"Console Application started\n")
screen.refresh()
InputContainer.refresh()
window.refresh()
running = True
while running:
rows, cols = screen.getmaxyx()
userIn = inputField.edit()[0:-1]
if userIn!="":
if str(userIn)=="stop":
running = False
window.addstr(f"Command Issued: {userIn}\n")
inputWindow.refresh()
inputWindow.clear()
window.refresh()
curses.wrapper(main)
Feel free to use this yourself.

how to check if any program is running in windows using python

I would like to use win32 in python to create 2 functions... 1. A function that checks if a certain application is running. 2. A function that checks if an application is installed...
I have tried the following to check if something is running;
def IsRunning(ProgramName):
if win32ui.FindWindow(None, ProgramName):
print("its running")
return True
else:
print("its not running!")
but the findwindow always throws an error if the program is not running before my program ever gets to the else statement and I do not know how to bypass that....
I needed to pass it like this;
def IsRunning(WindowName):
try:
if win32ui.FindWindow(None, WindowName):
print("its running")
return True
except win32ui.error:
print("its not running!")
return False
You need to put the window title exactly for it to pass the test and return True...
The next thing I want to write is a similar function that uses regular expressions to find any part of a title name...
Brilliant!!! Happy now :)
The only thing with this, is that if the Applications creator decides to change the title of the main window of the program you are trying to test for, it will no longer work... I was hoping for a much more robust way of doing it... i.e. through some kind of unique process code!
in any case this will do for the time being, but if anyone has a more definitive answer please let me know...

Text adventure in Python issue

I am working on a text adventure in Python. I'm very new to the concept of object oriented programming (and programming in general), so I'm not entirely sure what went wrong. Well, what I've done so far is made two methods; one that handles what the user types in, and one that dictates what will happen in the game, using other methods defining rooms that I will create in the future. One problem I have, though, is that I can't test the program by running it! When I run it, there is no prompt for user input - the program just ends without returning any error. There's not much code so maybe you could help me in determining the problem! I'm sure there's something really obvious in there I've forgotten...
class Main(object):
def handle_events(self, userinput, cmd):
self.userinput = userinput
self.cmd = cmd
userinput = raw_input('> ')
cmd = {'use' : use,'quit' : quit, 'help' : help}
if userinput[0] not in cmd:
print "Invalid command. Check [help] for assistance."
def main(self, handle_events):
print '''You are in a dark room filled with
strange and ominous objects.
After some feeling around, you think
you can make out a light switch.'''
self.userinput
if userinput[1] == 'switch':
print "You flicked the switch!"
Main().main
You are not calling your method. Main().main is just a reference to the method. To call it you need another set of parentheses: Main().main().

Dragon NaturallySpeaking Programmers

Is there anyway to encorporate Dragon NaturallySpeaking into an event driven program? My boss would really like it if I used DNS to record user voice input without writing it to the screen and saving it directly to XML. I've been doing research for several days now and I can not see a way for this to happen without the (really expensive) SDK, I don't even know that it would work then.
Microsoft has the ability to write a (Python) program where it's speech recognizer can wait until it detects a speech event and then process it. It also has the handy quality of being able to suggest alternative phrases to the one that it thinks is the best guess and recording the .wav file for later use. Sample code:
spEngine = MsSpeech()
spEngine.setEventHandler(RecoEventHandler(spEngine.context))
class RecoEventHandler(SpRecoContext):
def OnRecognition(self, StreamNumber, StreamPosition, RecognitionType, Result):
res = win32com.client.Dispatch(Result)
phrase = res.PhraseInfo.GetText()
#from here I would save it as XML
# write reco phrases
altPhrases = reco.Alternates(NBEST)
for phrase in altPhrases:
nodePhrase = self.doc.createElement(TAG_PHRASE)
I can not seem to make DNS do this. The closest I can do-hickey it to is:
while keepGoing == True:
yourWords = raw_input("Your input: ")
transcript_el = createTranscript(doc, "user", yourWords)
speech_el.appendChild(transcript_el)
if yourWords == 'bye':
break
It even has the horrible side effect of making the user say "new-line" after every sentence! Not the preferred solution at all! Is there anyway to make DNS do what Microsoft Speech does?
FYI: I know the logical solution would be to simply switch to Microsoft Speech but let's assume, just for grins and giggles, that that is not an option.
UPDATE - Has anyone bought the SDK? Did you find it useful?
Solution: download Natlink - http://qh.antenna.nl/unimacro/installation/installation.html
It's not quite as flexible to use as SAPI but it covers the basics and I got almost everything that I needed out of it. Also, heads up, it and Python need to be downloaded for all users on your machine or it won't work properly and it works for every version of Python BUT 2.4.
Documentation for all supported commands is found under C:\NatLink\NatLink\MiscScripts\natlink.txt after you download it. It's under all the updates at the top of the file.
Example code:
#make sure DNS is running before you start
if not natlink.isNatSpeakRunning():
raiseError('must start up Dragon NaturallySpeaking first!')
shutdownServer()
return
#connect to natlink and load the grammer it's supposed to recognize
natlink.natConnect()
loggerGrammar = LoggerGrammar()
loggerGrammar.initialize()
if natlink.getMicState() == 'off':
natlink.setMicState('on')
userName = 'Danni'
natlink.openUser(userName)
#natlink.waitForSpeech() continuous loop waiting for input.
#Results are sent to gotResultsObject method of the logger grammar
natlink.waitForSpeech()
natlink.natDisconnect()
The code's severely abbreviated from my production version but I hope you get the idea. Only problem now is that I still have to returned to the mini-window natlink.waitForSpeech() creates to click 'close' before I can exit the program safely. A way to signal the window to close from python without using the timeout parameter would be fantastic.

Categories