Error During Speech-Recognition Safety Loop - python

I am using PocketSphinx speech-to-text engine to perform a certain task (I don't think is important to add).
I want it to react when I say certain words (which it does), however, I want to create a sort of "safety loop" where I put the program into a loop that it can only get out of when I say a certain other word, just in case it accidentally picks up me saying the initial word and performing the action when I don't want it to. Though, I am having trouble with my loop. The loop is at the end of the function, but it is a recurring function, so the function will continuously be called until I physically turn it off.
def listen(): #Definition of listen() function.
wait = 0
print ("Listening!")
for word in speech:
word_string = str(word)
if (word_string == "START"): #Listens for the word "Start."
print("Primary Function Executed.")
if (word_string == "REST"): #Listens for the word "Rest."
print ("In loop")
wait = 1
while (wait == 1): #Safety loop.
for cap in speech:
cap_string = str(cap)
if (cap_string == "OKAY"):
listen()
So, I have tried this loop (the last 8 lines) without reassigning the variable "wait" to the value "1". However, then it just ignores the loop and I can say "Start" or "rest" and it will perform both functions whenever the words are said, which I don't want. I want to say "rest" to get into the loop, then "okay" to get out of it, but when I say "rest", I get another window (this is visual studios 2019 btw) that is called Break Mode, and it says
"No compatible code running. The selected debug engine does not support any code executing on the current thread (e.g. only native runtime code is executing)."
And there is another window that is titled "Exception Unhandled", which reads,
"Ad___enter__returned-1".
I know that the problem is the loop because if I ignore the loop, it runs smoothly, and it also prints "In loop", so I know that the "if" statement runs fine as well.

Ad___enter__returned-1
is the key to solving the problem. It tells you that the pocketsphinx engine has crashed for some reason. You can find more details looking at the log (should go to stderr by default).

Related

Python: how to envisage the interruption of a loop before its normal end

I have a loop running for quite a long time (several hours). It may be that the user, looking at the current results, considers the run iterations as sufficient and then wants to stop the loop before its natural end, but without interrupting the whole program (no "Ctrl+C") since some final results processing is necessary.
To do that, I added the possibility of creating a specific 'stop' file in the working directory. At each loop, the code verify if that file exists and, if that is the case, it end the loop. I do not know if this solution is efficient and whether better solutions exist.
Example
i = 0
while i < 1000 and not(path.isfile(path.join(self.wrkdir,'stop'))) :
DoSomeStuff
i += 1
FinalizingStuff
If the only reason for not using Ctrl+C is that you think it will stop all your program, then the best solution is to use it instead of watching the files.
Simply because you can catch this exception (it is called KeyboardInterrupt) in your code as any other and do whatever you want.
import time
try:
while True:
time.sleep(0.1)
except KeyboardInterrupt:
print('Ok, user is pissed with our loop, go further')
finally:
# if some resources need to be cleaned
pass
print('Here we are, nothing is lost')

Send a variable from outside the python console OR stop a script from outside

I wrote a Python script that executes an optimization and runs days to get a solution (due to the costly objective function). In all days work it will be sufficient to just stop the calculation at some point because the solution is good enough for me (but not for the optimization algorithm).
The problem is, I can always abort hitting Ctrl+C. But then there is no chance to nicely output the current best parameters, plot the data, save it etc. It would be great to stop the script in a controlled way after the next calculation of the objective function. So my thought was so question some variable (if user_stop=True) and programatically stop the optimization. But how to set such a variable? The python console is blocked during execution.
I thought about setting the content of a text file and reading it in each iteration but it's more than poor and hard to explain for other users of the script. Theoretically, I could also ask the user for an input but than the script won't run automatically (which it should until someone decides to stop).
Any ideas for my problem?
Basically that's it - stop the loop at some point but execute the print:
a = 0
while True:
a = a + 1
print(a)
If you poll your "variable" infrequently (say at most once every 20 seconds) then the overhead of testing for a file is negligible. Something like
import os
QUITFILE = "/home/myscript/quit_now.txt"
# and for convenience, delete any old QUITFILE that may exist at init time
... # days later
if os.path.isfile( QUITFILE)
# tidy up, delete QUITFILE, and exit
Then just echo please > home/myscript/quit_now.txt to tell your program to exit.
maybe you can use a do-while loop. holding your target in a varible
outside the loop and start looping the calculatio while <= your target calculation.
For Windows, I would use msvcrt.getch()
For example, this script will loop until a key is pressed, then, if it is q, prompt for the user to quit: (Note that the if statement uses 'short circuiting' to only evaluate the getch() - which is blocking - when we know that a key has been pressed.)
import msvcrt, time
while True: #This is your optimization loop
if msvcrt.kbhit() and msvcrt.getch() == 'q':
retval = raw_input('Quit? (Y/N) >')
if retval.lower() == 'y':
print 'Quitting'
break #Or set a flag...
else:
time.sleep(1)
print('Processing...')
If you place this if block at a point in the optimization loop where it will be frequently run, it will allow you to sop at a convenient point, or at least set a flag which you can check for at the end of each optimization run.
If you cannot place it somewhere where it will be frequently checked, then you can look at handling the KeyboardInterrupt raised by Ctrl-C
If you are running on Linux, or need cross-platform capability, have a look at this answer for getting the keypress.

Program Errors in VERY Specific Instance - Detailed

I've written a simple console program in Python to perform basic logical calculations. However, when I use any of the single letters r,s,t or u (lower case) as variables, the console simply stalls. It doesn't produce an error or anything, and I end up having to Ctrl+C (Keyboard Interrupt in Linux). However, using any other letters in the alphabet aside from these four, my program runs fine.
Here is a snip of the exact moment where the console stalls:
And another snip of right after I Keyboard Interrupt after a stall, and a successful run of the program:
Here is the code segment referenced when I use a Keyboard Interrupt:
# Since my userExpression string is going
# to have a variable length, I had to
# initialize another variable to keep
# up with it and make sure that the while
# loop runs until the updated string ends.
truthList = truthMachine(propNum)
exprLength = len(userExpression)
while whileCounter < exprLength:
if userExpression[whileCounter] in varDict:
userExpression = userExpression.replace(userExpression[whileCounter],"truthList[i][" + str(varDict[userExpression[whileCounter]]) + "]")
exprLength = len(userExpression)
whileCounter += 1
This portion of the program is just supposed to switch the lower case letter variable with its value in a dictionary that I created. Again, it works with any other letter in the alphabet and I've thoroughly tested more complicated logical propositions and they all work if I'm not using r,s,t or u. Hopefully someone here has seen something similar.

How to stop a for loop while in execution

I am currently running a program, which i expect to go on for an hour or two. I need to break out of the loop right now, so that rest of the program continues.
This is a part of the code:
from nltk.corpus import brown
from nltk import word_tokenize, sent_tokenize
from operator import itemgetter
sentences = []
try:
for i in range(0,55000):
try:
sentences.append(brown.sents()[i])
print i
except:
break
except:
pass
the loop is currently around 30,000. I want to exit and continue with the code (not shown here). Please suggest me how to such that, the program doesn't break exit completely. (Not like keyboard interrupt)
Since it is already running, you can't modify the code. Unless you invoked it under pdb, you can't break into the Python debugger to alter the condition to leave the loop and continue with the rest of the program. So none of the normal avenues are open to you.
There is one outside solution, which requires intimate knowledge of the Python interpreter and runtime. You can attach the gdb debugger to the Python process (or VisualStudio if you are on Windows). Then when you break in, examine the stack trace of the main thread. You will see a whole series of nested PyEval_* calls and so on. If you can figure out where the loop is in the stack trace, then identify the loop. Then you will need to find the counter variable (an integer wrapped in a PyObject) and set it to a large enough value to trigger the end of the loop, then let the process continue. Not for the faint of heart! Some more info is here:
Tracing the Python stack in GDB
Realistically, you just need to decide if you either leave it alone to finish, or kill it and restart.
It's probably easiest to simply kill the process, modify your code so that the loop is interruptible (as #fedorSmirnov suggests) with the KeyboardInterrupt exception, then start again. You will lose the processing time you have invested already, but consider it a sunken cost.
There's lots of useful information here on how to add support to your program for debugging the running process:
Showing the stack trace from a running Python application
I think you could also put the for loop in a try block and catch the keyBoardInterrupt exception by proceeding with the rest of the program. With this approach, you should be able to break out of the loop by hitting ctrl + C while staying inside your program. The code would look similar to this:
try:
# your for loop
except KeyboardInterrupt:
print "interrupted"
# rest of your program
You can save the data with pickle before the break command. Next time load the data and continue the loop.

Python / LibTCOD - libtcod.console_wait_for_keypress(True) triggering twice for each input

I'm going through the Roguebasin python/libtcod roguelike tutorial. The problem I encounter is, every time key = libtcod.console_wait_for_keypress(True) is called, the main loop fires off not one, but two times. The code handling keyboard input is as follows:
def handle_keys():
#key = libtcod.console_check_for_keypress() #real-time
key = libtcod.console_wait_for_keypress(True) #turn-based
if key.vk == libtcod.KEY_ENTER and key.lalt:
#Alt+Enter: toggle fullscreen
libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
elif key.vk == libtcod.KEY_ESCAPE:
return 'exit' #exit game
if game_state == 'playing':
#movement keys
if libtcod.console_is_key_pressed(libtcod.KEY_UP):
player_move_or_attack(0, -1)
elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN):
player_move_or_attack(0, 1)
elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT):
player_move_or_attack(-1, 0)
elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT):
player_move_or_attack(1, 0)
else:
return 'didnt-take-turn'
The code is lifted verbatim (save for the extra four-space indentation) from this part of the tutorial. Note there are two code versions on that page. I have my own version written up, but I encounter the problem even with a direct copy/paste. As far as I can tell, the problem permeates the whole tutorial.
console_wait_for_keypress(True) is supposed to wait for a single key and put it in "key" variable, so I can react to it. All other input is supposed to be flushed. Then new iteration of main loop calls console_wait_for_keypress(True) again, which is supposed to wait for new input, and so on. Instead, every second iteration of console_wait_for_keypress(True) triggers without waiting for a new input.
The game actually works fine, since the second input does not trigger any of the console_is_key_pressed() conditions, and the handle_keys() function returns 'didnt-take-turn', which tells game logic to do nothing. This still means for every cycle, two are spent instead, which is not the desired behaviour. The problem is easy to observe if you print the result of handle_keys() every cycle. It alternates between 'None' and 'didnt-take-turn'.
I am honestly stumped on this. Simply holding down a directional button seems to not produce 'didnt-take-turn' output, but the function is supposed to be used for single keypresses. It can't be too short a delay, since a normal keypress always produces exactly two outputs. The libtcod documentation fails to help me.
What should I do to make a single keystroke trigger only a single console_wait_for_keypress()?
It's fixed in the last svn:
http://doryen.eptalys.net/forum/index.php?topic=1500.msg8507#msg8507
or here:
https://bitbucket.org/jice/libtcod

Categories