Why do you have to fill python input before suspending debugger? - python

I debugging in PyCharm.
I insert a breakpoint at the line:
p_result = input('Who will win: ')
Now usually the debugger stops without executing the line where the breakpoint is. However this time I have to make an input before the thread is suspended.

Related

How to terminate python script safely so that it's finally block executes

I have started a python script in nohup. The script contains a finally block which will print the remaining items in the queue to print into a log file, if any Exception OR Keyboard interrupt occurs.
It is working fine as long as I'm in the same shell from where I executed the script. For eg: below steps are working as I have expected.
# Run the script in the background with nohup
nohup script_name.py > script_name.log 2>&1 &
# List the processes currently running in the background
jobs
# Bring back the process to foreground
fg 1
# Send Keyboard interrupt to stop the process by allowing to execute finally code block
Press CTRL+C
The script prints all the pending items in the queue to the "script_name.log" file.
But the problem is, once I exit the current shell from where I have started the "nohup" process, I can no longer bring that process back to foreground to send Keyboard interrupt.
At the same time, if I use kill PROCESS_ID command, it is not allowing the finally block to execute, so I'm also loosing the pending items in the queue.
Is there is any way I can terminate the process OR send a Keyboard interrupt to nohup process, still by allowing finally block to execute the code?
Thank you.
UPDATED: High level python code:
It is actually a Python project with lot of directories and other scripts but let me give only the finally block part of the code here.
try:
cc = crawler.MultiThreadedWebCrawler(max_workers)
cc.run_web_crawler()
finally:
cc.info(script_start_time)
# Inside another script, the definition of "info" method is,
def info(self, script_start_time):
print('\n', self.crawl_queue.qsize(), ' URLs in crawl_queue are:\n')
while self.crawl_queue.qsize() > 0:
print(self.crawl_queue.qsize(), ' ', self.crawl_queue.get(), '\n')
print("Script execution started at ", script_start_time)
print("Script execution ended at ", datetime.now().strftime('%Y-%m-%d__%H_%M_%S'))
Use the value inside a txt file as a kill switch.
Have your program open a txt file every time it's finished it's 'jobs'. Check to see if the value extracted is a 1 or a 0. If it's 0 then continue. If it's 1 then exit the script and output the results.
KillOrStay = open("/root/KillOrStay.txt").readlines()[0]
if int(KillOrStay) == 1:
# Output your results here
exit()
else:
pass

RPi - Python Curses program running at boot does not have keyboard focus

I am trying to write a program that will run when my raspberry pi starts up and will allow me to immediately begin typing things with my keyboard and have it be picked up by the program. I don't want to have to manually start the program when the pi starts. I need to use curses (or a similar unbuffered keyboard input library) because I display what I am typing on a 2x16 I2C LCD, but I also need everything that I am typing to be recorded to a text file.
Right now, I am auto-starting the program at boot by putting a line in rc.local. This works, and the I2C display is correctly showing program output, but it does not respond to keyboard input, and the keyboard input is instead displayed (when I connect the pie to a screen, the goal is to run headless) on an odd console layout that exits when I press enter and says -bash: 'whatever I just typed' command not found.
I have already tried:
Setting a timer at the beginning of the program to wait until the pi has fully booted before initializing the curses window and keyboard capture
Creating a seperate python program to wait until the pi has fully booted and then running the main script by importing it
Neither of these methods works though, I get the same problem with slight differences.
To be clear, the program works flawlessly if I run it manually from the command line. But there is no keyboard input to the program (or at least not where it is supposed to be inputted) when I autostart the script with rc.local.
My code:
#!/usr/bin/python
import I2C_LCD_driver, datetime, sys
from time import *
from subprocess import call
mylcd = I2C_LCD_driver.lcd()
for x in range(30): #waits for raspberry pi to boot up
mylcd.lcd_display_string("Booting Up: "+str(x), 1)
sleep(1)
import curses
key = curses.initscr()
curses.cbreak()
curses.noecho()
key.keypad(1)
key.nodelay(1)
escape=0
while escape==0:
#variable initialization
while 1:
k=key.getch()
if k>-1: #runs when you hit any key. getch() returns -1 until a key is pressed
if k==27: #exits the program when you hit Esc
break
elif k==269:
# a couple other special Function key cases are here
else:
inpt=chr(k)
mylcd.lcd_display_string(inpt,2,step) #writes the last character to the display
#some more code that handles writing the text to the LCD, which works flawlessly when run manually.
file.write("%s\r\n" % entry)
file.close()
mylcd.lcd_display_string("Saved ",2)
mylcd.lcd_display_string("F1 New F2 PwrOff",1)
while 1:
k=key.getch()
if k>-1:
if k==265: #do it again! with F1
mylcd.lcd_clear()
break
elif k==266: #shut down with F2
escape=1
break
curses.nocbreak()
key.keypad(0)
curses.echo()
curses.endwin()
call("sudo shutdown -h now", shell=True)
The line that I have in /etc/rc.local is as follows if that is important:
sudo python3 journal.py &
and it is followed by the 'exit 0' line.
Thanks for any help you can provide. I know this is a very specific problem and will be tedious to reproduce, but if anyone knows anything about autostarting functions I would be very appreciative of any tips.
Ok, literally all I had to do (which I did find after some more research on stackexchange, this is the thread that contained the answer I was looking for) was run my program from ~/.bashrc instead of /etc/rc.local. This method works perfectly, exactly what I wanted.
This should be because of how you called the program:
python3 journal.py &
You may want to check out JOB CONTROL of bash (or your shell) man page:
Only foreground
processes are allowed to read from ... the terminal. Background processes which
attempt to read from ... the
terminal are sent a SIGTTIN ... signal by the kernel's terminal
driver, which, unless caught, suspends the process.
In short, once curses (or anything for that matter) try to read from stdin your process is likely stopped (after it may have already written to your display). Keep it in the foreground to be able to have it use stdin (and by extension keyboard).
Side note: Not sure about distro and details of implementation of rc.local in your case, but aren't init scripts normally run with uid/gid 0 already (without wrapping individual calls through sudo?)

Code still executes after "quit" or "exit", Python, Spyder

from os.path import join
string=" Congratulations, you are about to embark upon one of life’s "
path=r"C:\Users\Nord.Kind\Desktop"
file="test.txt"
quit()
# This should not execute, but it does!!
with open(join(path,file),"w")as wfile:
wfile.write(string)
wfile.close()
In the above code example the code still executes the write in file command, even though its after a quit.
The same behavious occures when I use exit.
I am using Spyder 3.6
Also the kernel restarts each time I use exit or quit.
Any help?
(Spyder maintainer here) Your question contains this comment:
Also the kernel restarts each time I use exit or quit.
That's the behavior of the IPython kernel we use as a backend to execute users code. Those commands kill the kernel and that forces a kernel restart to maintain its associated console active. I'm afraid there's nothing you can do about it.
Note: The same happens in the Jupyter notebook.
One way is to use sys.exit() in lieu of quit()
import sys
... # code that executes
sys.exit()
... # this code won't execute
However, as noted by #AranFey in the comments, your code will throw an error if it attempts to execute the last part where the variable read is not defined.
You can use SystemExit:
# Code that will run
raise SystemExit
# Code that will not run
sys.exit() also raises this error but this doesn't require importing sys.

Python 3.4.3 program does not work outside the IDE

I am a beginner and wrote the following in Python 3.4.3 using Wing IDE 1.0.1
sidea = float( input ( " eerste rechtshoekzijde:") )
sideb= float ( input ( "tweede rechtshoekzijde:") )
tussenstap= sidea *sidea + sideb * sideb
print( int( tussenstap))
sidec= int( tussenstap **0.5)
print("de lengte van de lange zijde is", sidec)
In the IDE environment it works just fine. But when I double click on the program after saving it does not work. I can enter variable 1 and variable 2, but when I press Enter, it shows the answer in a split second and the screen disappears.
It is configured well, so there is no problem with version 2 on one hand en 3 on the other hand. Can someone please help me?
it shows the answer in a split second and the screen disappears.
That’s because when you double-click the .py file in Windows, a new console application running your Python script is launched. And that console application terminates as soon as your script is done doing whatever it does.
So in your case, it asks for input, and then prints something; and then it’s done doing things. So the Python process terminates and the window disappears.
A very common solution to this “problem” is to ask for some final input at the end of your script:
print("de lengte van de lange zijde is", sidec)
input('Press enter to quit this application')
So now, we’re just asking the user to press enter, and only then the script is done doing things and the window may disappear.
Another solution would be to simply launch your script inside an existing console application, so that when the Python process terminates, the window returns to your console instead of closing itself. To do this, launch the Windows command line, e.g. by starting cmd from the Run-window (WinKey + R), and then typing python myscript.py. This will launch the myscript.py in the current directory, without terminating the console process after the script finishes.
Just open a console and run the program with the following command:
python
By doing that the console won't close right after the program finishes

setting breakpoint in pdb python

I want to set breakpoints using pdb and then run the loop in the program until that breakpoint. and then after checking the values keep continuing (only stopping at that point) until the loop ends. how do i do it?
You can run your program into pdb from the command line by running
python -m pdb your_script.py
This will stop execution at line 1, now set breakpoint with b linenumber e.g. b 25. Now type run it will run the program until that break point.
If you can modify the code, one way is to add this line where you want to break:
import pdb; pdb.set_trace()

Categories

Resources