I have this code for a parking system. When the number of spaces goes above 20 it sends and error message due to 20 being the limit of spaces. I want to try shutdown the program after this point.
I have tried doing what you can do in Python. This is:
import sys
display.scroll("Error: Limit exceeded.")
sys.exit()
This gives me an attribute error.
from microbit import *
import sys
elif spaces > 20:
display.scroll("Error: The spaces have exceeded the limit.")
sys.exit()
This should shutdown the program, not letting it to function, after the elif statement. There is more code (if statements, loops, function) but it is irrelevant.
Thanks :)
There's a couple ways I can think of.
In general, you can just enter an infinite loop, which will effectively halt everything, if there's no way to interrupt the loop:
while True:
microbit.sleep(1000000) # wait for 1000 seconds until the end of time
In micro:bit's documentation there's also microbit.panic(), which, quote, "requires a restart" of the micro:bit:
microbit.panic(0)
You could see if that works for you.
And since the micro:bit uses MicroPython as its Python implementation, you can look here in the MicroPython documentation:
import pyb
pyb.stop() # stop CPU, waiting for external interrupt
However, if an external interrupt does occur (and one might), the program would then probably continue.
Your code snippet is a bit misleading as it must be in a while True: loop. Just breakout of that outer loop.
Related
I created a simple bind script. It works on IDLE Python but it doesn't work in CS:GO. Do you know why?
Mayby it must be on background to work?
import keyboard
import pyautogui
import time
def EventListen():
while True:
try:
if keyboard.is_pressed('n'):
pyautogui.press('`')
pyautogui.typewrite('say EZ')
pyautogui.press('enter')
pyautogui.press('`')
EventListen()
except:
EventListen()
EventListen()
I don't see the need to use pyautogui since you are already using keyboard which is sufficient to perform the tasks you need. I have made some changes to your code
import time
import keyboard
def EventListen():
while True:
try:
if keyboard.is_pressed('n'):
keyboard.press('`')
keyboard.write('say EZ')
keyboard.press('enter')
keyboard.press('`')
elif keyboard.is_pressed('/'): #add something to end the process
break
except:
EventListen()
time.sleep(0.001)
EventListen()
There is no need to call the function in the while loop, as it will anyway be executed infinitely unless you kill the process. I don't see why the script wouldn't run in the background, in fact I am typing this
n`say EZ
`
using the script. What might be possible is that your previous program ran continuously, causing high CPU usage which might have competed with the game's demand. I recomend you to add a small delay before every iteration of the while loop, in this case I have added 1 ms delay, which will cause significant reduction in CPU usage. I am not sure if that solved your problem as I am unable to reproduce your exact case, let me know if it helped.
EDIT : I forgot to mention, I have added another binding of keyboard.is_pressed('/') which will make the program break out of the loop and hence terminate it when / key is pressed. You can change this as you like. If you don't want any other binding as such (which I don't recommend) then you can rely on manually killing the task.
you should make an exe with pyinstaller and you run it background
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.
Im trying to get wifite (https://github.com/derv82/wifite) working on my 16x2 Adafruit LCD (http://www.adafruit.com/product/1110).
But for some Reason, if I press the specified button nothing happens.
I want to replace all pieces of code that look like this:
try
....
except KeyboardInterrupt:
....
With the code for the LCD Buttons:
try
....
except lcd.buttonPressed(lcd.SELECT):
....
But for some reason nothing happens if I press the button, I don't get a error - And wifite just keeps doing it's thin.
Any Idea why this isn't working how it should ?
Or is there maybe a better way ?
As others have pointed out except KeyboardInterrupt ... is a special construct in Python ... because a [Ctrl]-[C] is handled by your terminal driver and presents an "Interrupt" signal to your program (SIGINT under Unix, Linux and similar operating systems). (There is similar handling under Microsoft operating systems, with different details and slightly different terminology; but the Python code works the same either way.
There are other ways of accessing various other forms of hardware event ... and the Python exception module is not a typical way for those to be implemented.
In the case of the AdaFruit, or other Rasberry Pi devices, you'd use the modules they include with their package. You've already seen it, and presumably done the required import in your code (based on your reference to lcd.buttonPressed()). The problem is that this isn't how you use that function at all.
Read this carefully: https://blog.soton.ac.uk/pi/modules-available/adafruit-rgb-lcd-display/
... it includes example which show how you should be using it. That should be something like:
#!python
# Set up stuff here ...
got_event = False
while not got_event:
if lcd.buttonPressed(lcd.SELECT)
got_event = True
break
# Do other stuff, perhaps
# Or time.sleep(0.1)?
if got_event:
# In case we had other exit conditions from doing other stuff?
subprocess.call(YOUR_OTHER_PROGRAM)
Of course their code is a complete running program. I'm only highlighting a couple of points here. You need to loop around until you get the event your looking for (or loop around forever processing these events for as long as your device is up).
The lcd.buttonPressed() method is checking to see if the button has been pressed since the last time it was cleared; but the method/function doesn't block ... it returns True or False (or possibly None --- that wouldn't affect these code examples --- any "false" value means the button has not been pressed).
You want to sleep for some amount of time between checks. They use a half second delay in their example; I used a tenth of a second. (People will typically perceive a response within a tenth of a second from a computerized device as "instantaneous" while a half second delay will, typically, be slightly annoying). Checking as fast as you can will just needlessly heat up the electronics. Even a 0.01 (one hundredth of a second) sleep is sufficient ... but 0.05-0.1 are probably the best practice for something like this.
If I understand correctly, you want to have one of the buttons on the Adafruit LCD panel interrupt the program at almost any stage. (It would have been great if you'd mentioned this yourself!)
KeyboardInterrupt is a signal sent to a process, usually when a user presses Ctrl + c on a keyboard. To be more precise, a signal is sent by the OS and caught by the Python runtime, which raises a KeyboardInterrupt exception.
However, Ctrl + c is special! In almost any other case, when a user presses a key or a button, this is not translated into a special signal.
I'm not sure how you could get the behavior you want; this may depend quite a bit on the operating system you are using.
What you need is event detection try something like this. You might have to get familiar with Tkinter
from Tkinter import *
root = Tk()
def callback_end(event)
# do whatever ending procedure you want here
quit()
def main()
# do everything in your main code here
if lcd.buttonPressed(lcd.SELECT):
callback_end("<End>")
root.after(Period,main)
root.bind("<End>",callback_end) # if you press the end key it will call the callback_end function
root.after(Period,main) # repeats main every Period in miliseconds
root.mainloop()
I realize that this is not a complete answer but I hope it gets you going in the right direction
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.
I am trying to have my code detect when a flashdrive is plugged in and then continue the code. I am currently using "os.path.exists". When I start the code with the flashdrive plugged in, the code functions fine, however, if I start when the flashdrive is unplugged, and attempt to plug it in while the code is running, the code never checks to see if the flashdrive is plugged in and keeps forcing the code to sleep. How can I get the code to work?
import os
import sys
import datetime
from datetime import datetime
import shutil
import time
#Wait for FlashDrive to be connected
if os.path.exists("F:\"):
connected = 1
else:
connected = 0
while connected == 0:
print "..."
time.sleep(10)
#Get current date
currentdate=datetime.now().strftime("%m-%d-%Y")
print "Photos saved: " + currentdate
#Copy and rename DCIM
src = "F:/Pictures"
dst = "C:/Users/Josh/Desktop/photos/" + currentdate
shutil.copytree(src, dst)
The code is supposed to be a loop and execute every time an iPhone connects and never stop running, but I cannot get the code to work if it does not really check for the flashdrive.
Cycle with some arbitrary sleeps isn't a good idea (at all). It makes your program less responsive to the event, because it will take at least N ms to catch an event fired at the start of the iteration*. Also it wastes CPU due to a large amount of API calls.
Create a window.
Listen to WM_DEVICECHANGE message in your message loop. It will fire every time your device configuration changed, but won't tell you, how.
On such event, ask for current configuration.
You can find a tutorial here. Also, take a look at the similar answer on SO.
(*) Actually sleep will test on each next system tick if time_passed >= sleep_timeout. If so, it will return to the program. Problem is that system tick could be 1/18 of second on an old PC (56 ms), so you'll never have 10 ms delay.
Your problem is htat you set the connected variable outside the loop so it's never updated.
Try:
while not os.path.exists('F:\'):
print("...")
time.sleep(10)
--edit---
Then, wait for it to be removed at the end:
while os.path.exists('F:\'):
print("...")
time.sleep(10)
And, finally, wrap the entire thing in a big while True: so that the whole program repeats.
(Again, I do agree this is a 'hackish' and inefficent way to do this task)