I am trying to open an Excel file and to take the columns according to the names (headings). If it doesn't find those headings, I want the script to stop and display a message that the column was not found.
I first assign the current numbers to the columns with those names, and then I search for the name in the headings to make sure there were no columns inserted in between that will alter the column numbers. If the number is not the same, it will take whatever column number the name is in.
I have been trying to put an "else" under the "elif" and asking it to print an error and then I put a "break". The problem is that it doesn't stop the script if a column name is not found, it just takes the default assignment. I do understand why that break won't stop the whole script, but I don't know how to put it in order to stop it. The code is a bit more complex than just this, but I hope this will give a good understanding.
I also tried removing the default assignment but then it says that it can't find "i" so it gives me an error.
I would really appreciate some help.
Code:
colTPNumber = 2
colTDNumber = 3
rows = sheet.iter_rows(min_row=1, max_row=1)
firstRow = next(rows)
for i in firstRow:
if str(i.value) == "TP":
colTPNumber = i.column
elif str(i.value) == "TD":
colTDNumber = i.column
else:
print ("Column name not found")
break
break exits the loop, not the whole program.
Use exit() or sys.exit() (don't forget to import sys for the second option) to exit the program
Example:
import sys #unnessary if you're using exit() only
colTPNumber = 2
colTDNumber = 3
rows = sheet.iter_rows(min_row=1, max_row=1)
firstRow = next(rows)
for i in firstRow:
if str(i.value) == "TP":
colTPNumber = i.column
elif str(i.value) == "TD":
colTDNumber = i.column
else:
print ("Column name not found")
#break
sys.exit()
#OR
exit()
Some more info:
You can also use quit()
quit() raises the SystemExit exception behind the scenes.
Furthermore, if you print it, it will give a message:
>>> print (quit)
Use quit() or Ctrl-Z plus Return to exit
This functionality was included to help people who do not know Python. After all, one of the most likely things a newbie will try to exit Python is typing in quit.
Nevertheless, quit should not be used in production code. This is because it only works if the site module is loaded. Instead, this function should only be used in the interpreter.
exit() is an alias for quit (or vice-versa). They exist together simply to make Python more user-friendly.
Furthermore, it too gives a message when printed:
>>> print (exit)
Use exit() or Ctrl-Z plus Return to exit
However, like quit, exit is considered bad to use in production code and should be reserved for use in the interpreter. This is because it too relies on the site module.
sys.exit raises the SystemExit exception in the background. This means that it is the same as quit and exit in that respect.
Unlike those two however, sys.exit() is considered good to use in production code. This is because the sys module will always be there.
os._exit exits the program without calling cleanup handlers, flushing stdio buffers, etc. Thus, it is not a standard way to exit and should only be used in special cases. The most common of these is in the child process(es) created by os.fork.
Note that, of the four methods given, only this one is unique in what it does.
Summed up, all four methods exit the program. However, the first two are considered bad to use in production code and the last is a non-standard, dirty way that is only used in special scenarios.
So, if you want to exit a program normally, go with the third method: sys.exit.
Or, even better in my opinion, you can just do directly what sys.exit does behind the scenes and run:
raise SystemExit
This way, you do not need to import sys first.
However, this choice is simply one on style and is purely up to you
Adapted from: https://www.edureka.co/community/16988/python-exit-commands-why-so-many-and-when-should-each-be-used
More info on sys.exit():
sys.exit([arg])
Exit from Python. This is implemented by raising the SystemExit exception, so cleanup actions specified by finally clauses of try statements are honored, and it is possible to intercept the exit attempt at an outer level.
The optional argument arg can be an integer giving the exit status (defaulting to zero), or another type of object. If it is an integer, zero is considered “successful termination” and any nonzero value is considered “abnormal termination” by shells and the like. Most systems require it to be in the range 0–127, and produce undefined results otherwise. Some systems have a convention for assigning specific meanings to specific exit codes, but these are generally underdeveloped; Unix programs generally use 2 for command line syntax errors and 1 for all other kind of errors. If another type of object is passed, None is equivalent to passing zero, and any other object is printed to stderr and results in an exit code of 1. In particular, sys.exit("some error message") is a quick way to exit a program when an error occurs.
Since exit() ultimately “only” raises an exception, it will only exit the process when called from the main thread, and the exception is not intercepted.
Changed in version 3.6: If an error occurs in the cleanup after the Python interpreter has caught SystemExit (such as an error flushing buffered data in the standard streams), the exit status is changed to 120.
From https://docs.python.org/3/library/sys.html
Give the variables invalid default values, so you can check them after the loop.
Then you can call exit() if they're not set correctly, this will terminate the entire script.
colTPNumber = None
colTDNumber = None
rows = sheet.iter_rows(min_row=1, max_row=1)
firstRow = next(rows)
for i in firstRow:
if str(i.value) == "TP":
colTPNumber = i.column
elif str(i.value) == "TD":
colTDNumber = i.column
if colTPNumber is None or colTDNumber is None:
print("Column name not found")
exit(1)
See Terminating a Python script
Try using exit() instead of break. break ends a loop, but exit() actually exits your program.
Related
How do I exit a script early, like the die() command in PHP?
import sys
sys.exit()
details from the sys module documentation:
sys.exit([arg])
Exit from Python. This is implemented by raising the
SystemExit exception, so cleanup actions specified by finally clauses
of try statements are honored, and it is possible to intercept the
exit attempt at an outer level.
The optional argument arg can be an integer giving the exit status
(defaulting to zero), or another type of object. If it is an integer,
zero is considered “successful termination” and any nonzero value is
considered “abnormal termination” by shells and the like. Most systems
require it to be in the range 0-127, and produce undefined results
otherwise. Some systems have a convention for assigning specific
meanings to specific exit codes, but these are generally
underdeveloped; Unix programs generally use 2 for command line syntax
errors and 1 for all other kind of errors. If another type of object
is passed, None is equivalent to passing zero, and any other object is
printed to stderr and results in an exit code of 1. In particular,
sys.exit("some error message") is a quick way to exit a program when
an error occurs.
Since exit() ultimately “only” raises an exception, it will only exit
the process when called from the main thread, and the exception is not
intercepted.
Note that this is the 'nice' way to exit. #glyphtwistedmatrix below points out that if you want a 'hard exit', you can use os._exit(*errorcode*), though it's likely os-specific to some extent (it might not take an errorcode under windows, for example), and it definitely is less friendly since it doesn't let the interpreter do any cleanup before the process dies. On the other hand, it does kill the entire process, including all running threads, while sys.exit() (as it says in the docs) only exits if called from the main thread, with no other threads running.
A simple way to terminate a Python script early is to use the built-in quit() function. There is no need to import any library, and it is efficient and simple.
Example:
#do stuff
if this == that:
quit()
Another way is:
raise SystemExit
You can also use simply exit().
Keep in mind that sys.exit(), exit(), quit(), and os._exit(0) kill the Python interpreter. Therefore, if it appears in a script called from another script by execfile(), it stops execution of both scripts.
See "Stop execution of a script called with execfile" to avoid this.
While you should generally prefer sys.exit because it is more "friendly" to other code, all it actually does is raise an exception.
If you are sure that you need to exit a process immediately, and you might be inside of some exception handler which would catch SystemExit, there is another function - os._exit - which terminates immediately at the C level and does not perform any of the normal tear-down of the interpreter; for example, hooks registered with the "atexit" module are not executed.
I've just found out that when writing a multithreadded app, raise SystemExit and sys.exit() both kills only the running thread. On the other hand, os._exit() exits the whole process. This was discussed in "Why does sys.exit() not exit when called inside a thread in Python?".
The example below has 2 threads. Kenny and Cartman. Cartman is supposed to live forever, but Kenny is called recursively and should die after 3 seconds. (recursive calling is not the best way, but I had other reasons)
If we also want Cartman to die when Kenny dies, Kenny should go away with os._exit, otherwise, only Kenny will die and Cartman will live forever.
import threading
import time
import sys
import os
def kenny(num=0):
if num > 3:
# print("Kenny dies now...")
# raise SystemExit #Kenny will die, but Cartman will live forever
# sys.exit(1) #Same as above
print("Kenny dies and also kills Cartman!")
os._exit(1)
while True:
print("Kenny lives: {0}".format(num))
time.sleep(1)
num += 1
kenny(num)
def cartman():
i = 0
while True:
print("Cartman lives: {0}".format(i))
i += 1
time.sleep(1)
if __name__ == '__main__':
daemon_kenny = threading.Thread(name='kenny', target=kenny)
daemon_cartman = threading.Thread(name='cartman', target=cartman)
daemon_kenny.setDaemon(True)
daemon_cartman.setDaemon(True)
daemon_kenny.start()
daemon_cartman.start()
daemon_kenny.join()
daemon_cartman.join()
from sys import exit
exit()
As a parameter you can pass an exit code, which will be returned to OS. Default is 0.
I'm a total novice but surely this is cleaner and more controlled
def main():
try:
Answer = 1/0
print Answer
except:
print 'Program terminated'
return
print 'You wont see this'
if __name__ == '__main__':
main()
...
Program terminated
than
import sys
def main():
try:
Answer = 1/0
print Answer
except:
print 'Program terminated'
sys.exit()
print 'You wont see this'
if __name__ == '__main__':
main()
...
Program terminated Traceback (most recent call last): File "Z:\Directory\testdieprogram.py", line 12, in
main() File "Z:\Directory\testdieprogram.py", line 8, in main
sys.exit() SystemExit
Edit
The point being that the program ends smoothly and peacefully, rather than "I'VE STOPPED !!!!"
Problem
In my practice, there was even a case when it was necessary to kill an entire multiprocessor application from one of those processes.
The following functions work well if your application uses the only main process. But no one of the following functions didn't work in my case as the application had many other alive processes.
quit()
exit(0)
os._exit(0)
sys.exit(0)
os.kill(os.getppid(), 9) - where os.getppid() is the pid of parent process
The last one killed the main process and itself but the rest processes were still alive.
Solution
I had to kill it by external command and finally found the solution using pkill.
import os
# This can be called even in process worker and will kill
# whole application included correlated processes as well
os.system(f"pkill -f {os.path.basename(__file__)}")
In Python 3.5, I tried to incorporate similar code without use of modules (e.g. sys, Biopy) other than what's built-in to stop the script and print an error message to my users. Here's my example:
## My example:
if "ATG" in my_DNA:
## <Do something & proceed...>
else:
print("Start codon is missing! Check your DNA sequence!")
exit() ## as most folks said above
Later on, I found it is more succinct to just throw an error:
## My example revised:
if "ATG" in my_DNA:
## <Do something & proceed...>
else:
raise ValueError("Start codon is missing! Check your DNA sequence!")
My two cents.
Python 3.8.1, Windows 10, 64-bit.
sys.exit() does not work directly for me.
I have several nexted loops.
First I declare a boolean variable, which I call immediateExit.
So, in the beginning of the program code I write:
immediateExit = False
Then, starting from the most inner (nested) loop exception, I write:
immediateExit = True
sys.exit('CSV file corrupted 0.')
Then I go into the immediate continuation of the outer loop, and before anything else being executed by the code, I write:
if immediateExit:
sys.exit('CSV file corrupted 1.')
Depending on the complexity, sometimes the above statement needs to be repeated also in except sections, etc.
if immediateExit:
sys.exit('CSV file corrupted 1.5.')
The custom message is for my personal debugging, as well, as the numbers are for the same purpose - to see where the script really exits.
'CSV file corrupted 1.5.'
In my particular case I am processing a CSV file, which I do not want the software to touch, if the software detects it is corrupted. Therefore for me it is very important to exit the whole Python script immediately after detecting the possible corruption.
And following the gradual sys.exit-ing from all the loops I manage to do it.
Full code: (some changes were needed because it is proprietory code for internal tasks):
immediateExit = False
start_date = '1994.01.01'
end_date = '1994.01.04'
resumedDate = end_date
end_date_in_working_days = False
while not end_date_in_working_days:
try:
end_day_position = working_days.index(end_date)
end_date_in_working_days = True
except ValueError: # try statement from end_date in workdays check
print(current_date_and_time())
end_date = input('>> {} is not in the list of working days. Change the date (YYYY.MM.DD): '.format(end_date))
print('New end date: ', end_date, '\n')
continue
csv_filename = 'test.csv'
csv_headers = 'date,rate,brand\n' # not real headers, this is just for example
try:
with open(csv_filename, 'r') as file:
print('***\nOld file {} found. Resuming the file by re-processing the last date lines.\nThey shall be deleted and re-processed.\n***\n'.format(csv_filename))
last_line = file.readlines()[-1]
start_date = last_line.split(',')[0] # assigning the start date to be the last like date.
resumedDate = start_date
if last_line == csv_headers:
pass
elif start_date not in working_days:
print('***\n\n{} file might be corrupted. Erase or edit the file to continue.\n***'.format(csv_filename))
immediateExit = True
sys.exit('CSV file corrupted 0.')
else:
start_date = last_line.split(',')[0] # assigning the start date to be the last like date.
print('\nLast date:', start_date)
file.seek(0) # setting the cursor at the beginnning of the file
lines = file.readlines() # reading the file contents into a list
count = 0 # nr. of lines with last date
for line in lines: #cycling through the lines of the file
if line.split(',')[0] == start_date: # cycle for counting the lines with last date in it.
count = count + 1
if immediateExit:
sys.exit('CSV file corrupted 1.')
for iter in range(count): # removing the lines with last date
lines.pop()
print('\n{} lines removed from date: {} in {} file'.format(count, start_date, csv_filename))
if immediateExit:
sys.exit('CSV file corrupted 1.2.')
with open(csv_filename, 'w') as file:
print('\nFile', csv_filename, 'open for writing')
file.writelines(lines)
print('\nRemoving', count, 'lines from', csv_filename)
fileExists = True
except:
if immediateExit:
sys.exit('CSV file corrupted 1.5.')
with open(csv_filename, 'w') as file:
file.write(csv_headers)
fileExists = False
if immediateExit:
sys.exit('CSV file corrupted 2.')
In Python 3.9, you can also use: raise SystemExit("Because I said so").
Just put at the end of your code quit() and that should close a python script.
use exit and quit in .py files
and sys.exit for exe files
I want to run a few instructions only if none of them throws an exception and skip all of them if at least one throws an exception.
I thought that was what a try-except would do but found out that the instructions inside of a try block are run until one instruction throws an exception, then the remaining instructions are skipped.
Some example code:
try:
print("I'm printing " + "1")
print("I'm printing " + "2")
print("I'm printing " + "3")
print("I'm printing " + "4")
except TypeError:
print("STOP there was an exception!")
The output of the example code will be as following:
I'm printing 1
I'm printing 2
STOP there was an exception!
as mentioned before the instructions inside the try block are run until an exception is thrown.
Whereas I wanted to achieve that either none or all instructions inside the try block are run. So the output would be:
STOP there was an exception!
How is such behavior implemented if possible?
EDIT:
I found a hacky way which works at least if KeyErrors should be avoided.
I used the try block to assign each value to itself, used except to skip an iteration if an exception was thrown and simply put the instructions of which either all or none should have been run after the except.
Code looked like this in the end:
try:
value1 = value1
value2 = value2
value3 = value3
except KeyError:
continue
func1(value1)
func1(value2)
func1(value3)
func1 will now only be applied on all values if none of them would throw a KeyError. I know that's probably quite a special case but that was my solution, in case someone has a similar problem.
As stated, this is not logically possible. However, there is a field of effort in critical sections and "commits" -- how can you "stage" a set of changes to your virtual world, and not commit those changes until you reach some level of acceptability?
The difficulty of implementation depends on the side effects within your try block. For instance, the version you posted is trivial: accumulate the desired output in a single string variable, which you emit only after the block is entirely successful. The side effect is the appearance of output in a medium which the program no longer controls.
Your program is a model of something. To make this conditional execution work, you need to create a virtual representation of your model. You operate on that representation until you reach a point of certainty, at which to foist your virtual changes on the main model. For instance, if you're working with a data base (a common paradigm for this problem), you either make a local copy and work on that, or you maintain a list of inverse operations to execute in case the sequence of changes fails (a complex "undo").
I hope these are enough leads to give you a concept of what you face, and how to find the appropriate direction for a total solution.
You can't break in between prints and tell I don't what to print the lines that are instructed to do so before. What printed are already printed.
One hacky way is to hold your instructions into a container and wrap it with a try - except:
instructions = []
try:
instructions = ["I'm printing " + "1", "I'm printing " + "2", "I'm printing " + 3, "I'm printing " + "4"]
except TypeError:
print("STOP there was an exception!")
print('\n'.join(instructions))
... which prints "STOP there was an exception!" if there is any TypeError else the instructions.
I am trying to run my code in parallel using the python "from multiprocessing import Process, Value" model.However, I am creating a shared variable and using it as flag, so if one process find the result it will set the flag value to 1 and exit.Other processes should exit when the flag value is changed but for some reason the flag value did not change for these processes. this is the code:
from multiprocessing import Process, Value
gflag= Value('i',0)#this is the global flag shared between process
gflag=0
while True:
if not piece:
break
list1= piece.splitlines()
p = Process(target=Dowork, args=(gflag,inValue,list1,var1,))
p.start()
if(gflag==1):
exit()
piece = f.read(10000)
def doWork(gflag,inputvalue,diclist,var1):
for p in diclist:
calResult= doSomeCal(p,var1)
if( calResult == inputvalue):
gflag=1
exit()
if(gflag==1):
print"exit now"
exit()
Question is how to stop all the threads when on of them find the result?
The main problem with your attempted solution is that, because you assign to gflag within doWork, it's a local variable, not a global. To fix that, you need to add global gflag at the start of the function.
But even if you fixed that, it wouldn't solve your problem. When you write gflag=1, that doesn't update the shared value stored in gflag, it just rebinds the name gflag to the local int 1. You want to use gflag.value. (Note that once you fix this, the previous problem goes away… but it's still often better to use the global declaration for human readers, even when the compiler doesn't need it.)
And finally, doWork doesn't actually check the flag until after it's finished doing all the work, so the flag doesn't help you to exit the child processes earlier. You probably want to put that if statement inside the for loop, so it checks the flag once per element, instead of only once at the end.
Full script here: http://pastebin.com/d6isrghF
I'll admit I'm very new to Python so please forgive my stupidity if this is an easy question to answer. The section in question is this:
sourcePath = jobPath
while os.path.basename(sourcePath):
if os.path.basename(os.path.dirname(sourcePath)).lower() == category.lower():
break
else:
sourcePath = os.path.dirname(sourcePath)
if not os.path.basename(sourcePath):
print "Error: The download path couldn't be properly determined"
sys.exit()
jobPath is being fed to the script from sabnzbd and is:
/mnt/cache/.apps/sabnzbd/complete/name.of.folder
category is:
tv
So I guess my question is: why is this failing with the error?
Why it does not work
Your code cannot work because while is executed until os.path.basename(sourcePath) is not evaluated to True, then if statement is called, which (because it looks like: if not os.path.basename(sourcePath)) is obviously evaluated as True and thus the message (your "error") is shown:
Annotated source code
sourcePath = jobPath
# This is executed until os.path.basename(sourcePath) is evaluated as true-ish:
while os.path.basename(sourcePath):
if os.path.basename(os.path.dirname(sourcePath)).lower() == category.lower():
break
else:
sourcePath = os.path.dirname(sourcePath)
# Then script skips to the remaining part, because os.path.basename(sourcePath)
# has been evaluated as false-ish (see above)
# And then it checks, whether os.path.basename(sourcePath) is false-ish (it is!)
if not os.path.basename(sourcePath):
print "Error: The download path couldn't be properly determined"
sys.exit()
When (and why) it sometimes works
It sometimes works only because category is found in the path, which means while loop will be exited (using break) even despite still meeting criteria (the condition after while keyword: os.path.basename(sourcePath)). Because the condition from while loop is still met (we exited the loop even though it was met), the next statement's condition (not os.path.basename(sourcePath)) is no longer met and the message ("the error") is not printed.
Possible solutions
I believe one of the solutions is to add a counter to your code, that will print the error only if in specific number of iterations you will not be able to find what you needed. You can also try to catch "too many recursions" exception (if you will use recursion, of course, but the error will be like this: RuntimeError: maximum recursion depth exceeded).
However, you should redesign it rather to meet your own needs.
Okay, so I'm writing a very simplistic password cracker in python that brute forces a password with alphanumeric characters. Currently this code only supports 1 character passwords and a password file with a md5 hashed password inside. It will eventually include the option to specify your own character limits (how many characters the cracker tries until it fails). Right now I cannot kill this code when I want it to die. I have included a try and except snippit, however it's not working. What did I do wrong?
Code: http://pastebin.com/MkJGmmDU
import linecache, hashlib
alphaNumeric = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",1,2,3,4,5,6,7,8,9,0]
class main:
def checker():
try:
while 1:
if hashlib.md5(alphaNumeric[num1]) == passwordHash:
print "Success! Your password is: " + str(alphaNumeric[num1])
break
except KeyboardInterrupt:
print "Keyboard Interrupt."
global num1, passwordHash, fileToCrack, numOfChars
print "What file do you want to crack?"
fileToCrack = raw_input("> ")
print "How many characters do you want to try?"
numOfChars = raw_input("> ")
print "Scanning file..."
passwordHash = linecache.getline(fileToCrack, 1)[0:32]
num1 = 0
checker()
main
The way to allow a KeyboardInterrupt to end your program is to do nothing. They work by depending on nothing catching them in an except block; when an exception bubbles all the way out of a program (or thread), it terminates.
What you have done is to trap the KeyboardInterrupts and handle them by printing a message and then continuing.
As for why the program gets stuck, there is nothing that ever causes num1 to change, so the md5 calculation is the same calculation every time. If you wanted to iterate over the symbols in alphaNumeric, then do that: for symbol in alphaNumeric: # do something with 'symbol'.
Of course, that will still only consider every possible one-character password. You're going to have to try harder than that... :)
I think you're also confused about the use of classes. Python does not require you to wrap everything inside a class. The main at the end of your program does nothing useful; your code runs because it is evaluated when the compiler tries to figure out what a main class is. This is an abuse of syntax. What you want to do is put this code in a main function, and call the function (the same way you call checker currently).
Besides printing, you need to actually exit your program when capturin KeyboardInterrupt, you're only printing a message.
This is what worked for me...
import sys
try:
....code that hangs....
except KeyboardInterrupt:
print "interupt"
sys.exit()
Well, when you use that try and except block, the error is raised when that error occurs. In your case, KeyboardInterrupt is your error here. But when KeyboardInterrupt is activated, nothing happens. This due to having nothing in the except part. You could do this after importing sys:
try:
#Your code#
except KeyboardInterrupt:
print 'Put Text Here'
sys.exit()
sys.exit() is an easy way to safely exit the program. This can be used for making programs with passwords to end the program if the password is wrong or something like that. That should fix the except part. Now to the try part:
If you have break as the end of the try part, nothing is going to happen. Why? Because break only works on loops, most people tend to do it for while loops. Let's make some examples. Here's one:
while 1:
print 'djfgerj'
break
The break statement will stop and end the loop immediately unlike its brother continue, which continues the loop. That's just extra information. Now if you have break in a something like this:
if liners == 0:
break
That's going to depend where that if statement is. If it is in a loop, it is going to stop the loop. If not, nothing is going to happen. I am assuming you made an attempt to exit the function which didn't work. It looks like the program should end, so use sys.exit() like I showed you above. Also, you should group that last piece of code (in the class) into a seperate function. I hope this helps you!