Program Errors in VERY Specific Instance - Detailed - python

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.

Related

Nuke Python run the same script / node multiple times without scriptOpen and scriptClose?

I've got a python script for (Foundry) Nuke that listens to commands and for every command received executes a Write node. I've noticed that if I don't do nuke.scriptOpen(my_renderScript) before nuke.execute(writeNode,1,1) and then after do nuke.scriptClose(my_renderScript), then the write command seems to execute but nothing is written to file, despite me changing knob values before I call execute again.
The reason I want to not use scriptOpen and scriptClose every time I execute -the same node- is for performance. I'm new to nuke, so correct me if I'm wrong, but it's inefficient to unload and reload a script every time you want to run a node inside it, right?
[EDIT] Here's a simple test script. Waits for command line input and runs the function, then repeats. If I move the script open and script close outside the looping / recursive function, then it will only write to file once, the first time. On subsequent commands it will "run", and nuke will output "Total render time: " in the console (render time will be 10x faster since it's not writing / doing anything) and pretend it succeeded.
# Nuke12.2.exe -nukex -i -t my_nukePython.py render.nk
# Then it asks for user input. The input should be:
# "0,1,0,1", "1024x1024", "C:/0000.exr", "C:/Output/", "myOutput####.png", 1, 1
# then just keep spamming it and see.
import nuke
import os
import sys
import colorsys
renderScript = sys.argv[1]
nuke.scriptOpen(renderScript)
readNode = nuke.toNode("Read1")
gradeNode = nuke.toNode("CustomGroup1")
writeNode = nuke.toNode("Write1")
def runRenderCommand():
cmdArgs = input("enter render command: ")
print cmdArgs
if len(cmdArgs) != 7:
print "Computer says no. Try again."
runRenderCommand()
nuke.scriptOpen(renderScript)
colorArr = cmdArgs[0].split(",")
imageProcessingRGB = [float(colorArr[0]), float(colorArr[1]), float(colorArr[2]), float(colorArr[3])]
previewImageSize = cmdArgs[1]
inputFileLocation = cmdArgs[2]
outputFileLocation = cmdArgs[3]
outputFileName = cmdArgs[4]
startFrameToExecute = cmdArgs[5]
endFrameToExecute = cmdArgs[6]
readNode.knob("file").setValue(inputFileLocation)
writeNode.knob("file").setValue(outputFileLocation+outputFileName)
gradeNode.knob("white").setValue(imageProcessingRGB)
print gradeNode.knob("white").getValue()
nuke.execute(writeNode.name(),20,20,1)
runRenderCommand()
nuke.scriptClose(renderScript)
runRenderCommand()
The problem was between the chair and the screen. Turns out my example works. My actual code that I didn't include for the example, was a bit more complex and involved websockets.
But anyway, it turns out I don't know how python scoping sintax works ^__^
I was making exactly this error in understanding how the global keyword should be used:
referenced before assignment error in python
So now it indeed works without opening and closing the nuke file every time. Funny how local scope declaration in python in this case in my code made it look like there's no errors at all... This is why nothing's sacred in scripting languages :)
Is there a way to delete this question on grounds that the problem turns out was completely unrelated to the question?
Well that took an unexpected turn. So yes I had the global problem. BUT ALSO I WAS RIGHT in my original question! Turns out depending on the nodes you're running, nuke can think that nothing has changed (probably the internal hash doesn't change) and therefore it doesn't need to execute the write command. In my case I was giving it new parameters, but the parameters were the same (telling it to render the same frame again)
If I add this global counter to the write node frame count (even though the source image only has 1 frame), then it works.
nuke.execute(m_writeNode.name(),startFrameToExecute+m_count,endFrameToExecute+m_count, continueOnError = False)
m_count+=1
So I gotta figure out how to make it render the write node without changing frames, as later on I might want to use actual frames not just bogus count increments.

Error During Speech-Recognition Safety Loop

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).

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.

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

Avoiding raw_input to take keys pressed while in a loop for windows

I am trying to make a program which has a raw_input in a loop, if anyone presses a key while the long loop is running the next raw_input takes that as input, how do I avoid that?
I don't know what else to add to this simple question. Do let me know if more is required.
EDIT
Some code
for i in range(1000):
var = raw_input("Enter the number")
#.... do some long magic and stuff here which takes afew seconds
print 'Output is'+str(output)
So if someone presses something inside the magic phase, that is take as the input for the next loop. That is where the problem begins. (And yes the loop has to run for 1000 times).
This works for me with Windows 7 64bit, python 2.7.
import msvcrt
def flush_input():
while msvcrt.kbhit():
msvcrt.getch()
I put the OS in the title, window 7 64 bit to be specific. I saw the
answers there. They do apply but by god they are so big. Aren't there
other n00b friendly and safer ways to take inputs?
Let me try to explain why you need to do such an elaborate process. When you press a key it is stored in a section of computer memory called keyboard buffer (not to be confused with stdin buffer). This buffer stores the key's pressed until it is processed by your program. Python doesn't provide any platform independent wrapper to do this task. You have to rely on OS specific system calls to access this buffer, and flush it, read it or query it. msvcrt is a MS VC++ Runtime Library and python msvcrt provides a wrapper over it. Unless you wan't a platform independent solution, it is quite straight forward.
Use msvcrt getch to read a character from console. msvcrt.kbhit() to test if a key press is present in the keyboard buffer and so on. So as MattH has shown, it just a couple of lines code. And if you think you are a noob take this opportunity to learn something new.
Just collect your input outside of the loop (before you enter the loop). Do you really want the user to enter 1000 numbers? well maybe you do. but just include a loop at the top and collect the 1000 numbers at the start, and store them in an array.
then on the bottom half change your loop so it just does all the work. then if someone enters something no the keyboard, it doesn't really matter anymore.
something like this:
def getvars(top=1000):
vars = []
for i in range(0,top):
anum = int(raw_input('%d) Please enter another number: ' % i))
vars.append(anum)
return vars
def doMagic(numbers):
top = len(numbers)
for number in numbers:
# do magic number stuff
print 'this was my raw number %s' % number
if __name__ == "__main__":
numbers = getvars(top=10)
doMagic(numbers)
presented in a different sort of way and less os dependent
There is another way to do it that should work. I don't have a windows box handy to test it out on but its a trick i used to use and its rather undocumented. Perhaps I'm giving away secrets... but its basically like this: trick the os into thinking your app is a screensaver by calling the api that turns on the screensaver function at the start of your magic calculations. at the end of your magic calculations or when you are ready to accept input again, call the api again and turn off the screensaver functionality.
That would work.
There is another way to do it as well. Since you are in windows this will work too. but its a fair amount of work but not really too much. In windows, the window that is foreground (at the top of the Z order) that window gets the 'raw input thread'. The raw input thread receives the mouse and keyboard input. So to capture all input all you need to do is create a function that stands up a transparent or (non transparent) window that sits at the top of the Z order setWindowPos would do the trick , have it cover the entire screen and perhaps display a message such as Even Geduld or Please wait
when you are ready to prompt the user for more input, you use showwindow() to hide the window, show the previous results, get the input and then reshow the window and capture the keys/mouse all over again.
Of course all these solutions tie you to a particular OS unless you implement some sort of try/except handling and/or wrapping of the low level windows SDK calls.

Categories