Hello guys is there any differences between print my output in "try" clause or putting it after "except" clause with "else:"?
here is the code:
try:
Value1 = int(input("Type the first number: "))
Value2 = int(input("Type the second number: "))
Output = Value1 / Value2
except ZeroDivisionError:
print("Attempted to divide by zero!")
else:
print(Output)
or this?
try:
Value1 = int(input("Type the first number: "))
Value2 = int(input("Type the second number: "))
Output = Value1 / Value2
print(Output)
except ZeroDivisionError:
print("Attempted to divide by zero!")
I mean which one is better? because the result is same.
Thanks.
Like you already know we are talking about error handling when we are using try...except.
When an error is generated by an operation (or other statements) Python will stop the try block execution and is passed down to the first except block that matches the raised exception.
In case there isn't an except clause that matches our exception, it is passed on the outer try statement. This until it's handled or no handler is found, the raised exception becomes an unhandled exception and execution stops with a message of the error traceback.
In addition to except block we can use a finally block, that will be executed regardless of whether an exception occurs, and else block. The last one is useful for code that must be executed if the try clause does not raise an exception.
Your examples
How you said this two pieces of code gives the same result. However, with we read on documentation page of Python we have this affirmation:
"The use of the else clause is better than adding additional code to the try clause because it avoids accidentally catching an exception that wasn’t raised by the code being protected by the try … except statement."
Simple speaking if you have different statements that raises the same error, but for one them you aren't interested in catching it, move it to else clause. Look on this question on stack to understand better.
So in your case you can let print statement in try block because you will not catch some particular exceptions from it and there isn't much difference in this case where you put the print statement. However, I think the second example is a good logic separation of type "If no errors where founded then let's execute print".
The else clause is run only when no exception is thrown.
So the reason why you'd want to put it in there is to make it explicit: you only want to print the output if there was no exception.
As you mentioned, in your code, there's no functional difference to what happens.
See the docs for more information.
The first one will work fine as per your expectations (assuming that you don't want to bring up the python error prompt and halt the program).
It simply prescribes that IF 2nd digit is zero then it won't print the Python error prompt and pass it to the print command (And that's how it should be). Otherwise, in every other case, no matter whatever the divisor is, it will always give an output, so that way you eliminate nearly all loopholes.
Suggestion:
Keep the input type as float instead of int, that way you'll be able to print the division for decimal numbers input also. Ex-2/3
Related
If I have a try except block in my python code, and the first line of my try statement raises an exception will it automatically move on to exception or will it finish the try block first?
try:
int(string)
string = "This was a mistake, can't int string"
except:
pass
Here is it checking if it can int(string), which it can't, and then it immediately moves onto except, or does it do the string assignment first?
When I run it, it seems like it stops right away, but I want to know if that's happening for sure or something else.
Thanks
Let's try it.
try:
1/0
print("what?")
except:
print("nope")
Output:
nope
>>>
When an exception is raised it moves on to the except.
From the python docs, I found this,
"The try statement works as follows.
First, the try clause (the statement(s) between the try and except keywords) is executed.
If no exception occurs, the except clause is skipped and execution of the try statement is finished.
If an exception occurs during execution of the try clause, the rest of the clause is skipped. Then if its type matches the exception named after the except keyword, the except clause is executed, and then execution continues after the try statement.
If an exception occurs which does not match the exception named in the except clause, it is passed on to outer try statements; if no handler is found, it is an unhandled exception and execution stops with a message as shown above."
Cheers!
Hope it helps!
#the try block is to run the process
try:
string = "This was a mistake, can't int string"
#you are parsing the string into an int
int(string)
#this block is to capture the exception when it is raised
except:
#here I am just printing the exception
print('Exception')
#the pass is to pass the execution and follow the remaining process.
pass
Output:
Exception
>>>
Well, that the whole point of an error handler. When an error occurs in out program, it crashes, it won't simply skip the error line.
try:
int(string)
string = "This was a mistake, can't int string"
except:
pass
So if the try block finishes even after an error occurred in the middle, then the error handler'd seem a bit pointless.
There seem to be some issue with your program and maybe your understanding of the try except block.
First of all, from the block of code you have provided, it seems to me like string isn't even defined yet when you try to pass int(string).
Secondly, the string variable which you seem to be defining under seems to me like is something you are trying to print to the console once the program spits out an error and passes to the except block. If this is what you are trying to do, then your code should look something like this:
try:
int(string)
except:
print("This was a mistake, can't int string")
If you were to run the code provided above, you would indeed confirm that the try except statement is working as it would print "This was a mistake, can't int string" into the console instead of giving an error. Hope this was somewhat helpful and understandable. You got this chief, keep grinding!
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'm reading some source code which contains a try..except block with an else: continue statement. It is somewhat similar to the following:
numerator = float(1)
denominator = float(2)
def do_divisions(numerator=numerator, denominator=denominator):
for _ in range(10):
try:
fraction = numerator / denominator
print "{numerator}/{denominator} = {fraction}".format(numerator=numerator, denominator=denominator, fraction=fraction)
denominator -= 1
except ZeroDivisionError:
print "You cannot divide by zero!"
return False
else:
continue
result = do_divisions()
I'm struggling to understand what the else: continue statement does. As I understand from https://docs.python.org/2.7/tutorial/controlflow.html, the else clause gets executed if no exception occurs, and continue continues with the next iteration of the loop. However, is this not what Python would do anyways?
In this case, yes, else: continue is redundant and it could be left out.
But if there were more code after the else: block, it would not be redundant because the continue statement would cause that code to be skipped. This is a reason that a programmer might want to use else: continue. For example, if the code in the try: block completes without an exception, then nothing more needs to be done about the current item in the loop, but if it does raise an exception, the program needs to catch that exception and do something else to clean up after it. That cleanup code could be placed after the else: block.
else is a part of the try clause syntax. It is the opposite of except. It means "do this if no exception happens". It has nothing to do with if-else (also, it has an unfortunate and confusing name. even some of the creators of python mention that, but it is too difficult to change it now)
The difference is that code in else executes only if no exception happens, while code following will execute regardless. In the code example you mention, it does nothing, as the loop would continue anyway!
I am learning Python and have stumbled upon a concept I can't readily digest: the optional else block within the try construct.
According to the documentation:
The try ... except statement has an optional else clause, which, when
present, must follow all except clauses. It is useful for code that
must be executed if the try clause does not raise an exception.
What I am confused about is why have the code that must be executed if the try clause does not raise an exception within the try construct -- why not simply have it follow the try/except at the same indentation level? I think it would simplify the options for exception handling. Or another way to ask would be what the code that is in the else block would do that would not be done if it were simply following the try statement, independent of it. Maybe I am missing something, do enlighten me.
This question is somewhat similar to this one but I could not find there what I am looking for.
The else block is only executed if the code in the try doesn't raise an exception; if you put the code outside of the else block, it'd happen regardless of exceptions. Also, it happens before the finally, which is generally important.
This is generally useful when you have a brief setup or verification section that may error, followed by a block where you use the resources you set up in which you don't want to hide errors. You can't put the code in the try because errors may go to except clauses when you want them to propagate. You can't put it outside of the construct, because the resources definitely aren't available there, either because setup failed or because the finally tore everything down. Thus, you have an else block.
One use case can be to prevent users from defining a flag variable to check whether any exception was raised or not(as we do in for-else loop).
A simple example:
lis = range(100)
ind = 50
try:
lis[ind]
except:
pass
else:
#Run this statement only if the exception was not raised
print "The index was okay:",ind
ind = 101
try:
lis[ind]
except:
pass
print "The index was okay:",ind # this gets executes regardless of the exception
# This one is similar to the first example, but a `flag` variable
# is required to check whether the exception was raised or not.
ind = 10
try:
print lis[ind]
flag = True
except:
pass
if flag:
print "The index was okay:",ind
Output:
The index was okay: 50
The index was okay: 101
The index was okay: 10
I've read three beginner-level Python books, however, I still don't understand exceptions.
Could someone give me a high level explanation?
I guess I understand that exceptions are errors in code or process that cause the code to stop working.
In the old days, when people wrote in assembly language or C, every time you called a function that might fail, you had to check whether it succeeded. So you'd have code like this:
def countlines(path):
f = open(path, 'r')
if not f:
print("Couldn't open", path)
return None
total = 0
for line in f:
value, success = int(line)
if not success:
print(line, "is not an integer")
f.close()
return None
total += value
f.close()
return total
The idea behind exceptions is that you don't worry about those exceptional cases, you just write this:
def countlines(path):
total = 0
with open(path, 'r') as f:
for line in f:
total += int(line)
return total
If Python can't open the file, or turn the line into an integer, it will raise an exception, which will automatically close the file, exit your function, and quit your whole program, printing out useful debugging information.
In some cases, you want to handle an exception instead of letting it quit your program. For example, maybe you want to print the error message and then ask the user for a different filename:
while True:
path = input("Give me a path")
try:
print(countlines(path))
break
except Exception as e:
print("That one didn't work:", e)
Once you know the basic idea that exceptions are trying to accomplish, the tutorial has a lot of useful information.
If you want more background, Wikipedia can help (although the article isn't very useful until you understand the basic idea).
If you still don't understand, ask a more specific question.
The best place to start with that is Python's list of built-in exceptions, since most you'll see derive from that.
Keep in mind that anybody can throw any error they want over anything, and then catch it and dismiss it as well. Here's one quick snippet that uses exceptions for handling instead of if/else where __get_site_file() throws an exception if the file isn't found in any of a list of paths. Despite that particular exception, the code will still work. However, the code would throw an uncaught error that stops execution if the file exists but the permissions don't allow reading.
def __setup_site_conf(self):
# Look for a site.conf in the site folder
try:
path = self.__get_site_file('site.conf')
self.__site_conf = open(path).read()
except EnvironmentError:
self.__site_conf = self.__get_site_conf_from_template()
Python's documentation: http://docs.python.org/2/tutorial/errors.html
For a high-level explanation, say we want to divide varA / varB. We know that varB can't equal 0, but we might not want to perform the check every time we do the division:
if varB != 0:
varA / varB
We can use exceptions to try the block without performing the conditional first, and then handle the behavior of the program based on whether or not something went wrong in the try block. In the following code, if varB == 0, then 'oops' is printed to the console:
try:
varA / varB
except ZeroDivisionError:
print 'oops'
Here is a list of exceptions that can be used: http://docs.python.org/2/library/exceptions.html#exceptions.BaseException
However, if you know how it may fail, you can just open a python console and see what exception is raised:
>>> 1 / 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
Exceptions are unexpected events that occur during the execution of a program. An exception might result from a logical error or an unanticipated situation.
In Python, exceptions (also known as errors) are objects that are raised (or thrown) by code that encounters an unexpected circumstance.
The Python interpreter can also raise an exception should it encounter an unexpected condition, like running out of memory. A raised error may be caught by a surrounding context that “handles” the exception in an appropriate fashion.
If uncaught, an exception causes the interpreter to stop executing the program and to report an appropriate message to the console.
def sqrt(x):
if not isinstance(x, (int, float)):
raise TypeError( x must be numeric )
elif x < 0:
raise ValueError( x cannot be negative )
Exceptions are not necessarily errors. They are things that get raised when the code encounters something it doesn't (immediately) know how to deal with. This may be entirely acceptable, depending on how you make your code. For instance, let's say you ask a user to put in a number. You then try to take that text (string) and convert it to a number (int). If the user put in, let's say, "cat", however, this will raise an exception. You could have your code handle that exception, however, and rather than break, just give the user a small message asking him to try again, and please use a number. Look at this link to see what I'm talking about: http://www.tutorialspoint.com/python/python_exceptions.htm
Also, you usually handle exceptions with a try, except (or catch) block. Example:
try:
integer = int(raw_input("Please enter an integer: "))
except Exception, exc:
print "An error has occured."
print str(exc)
Hope it helps!