Python - Control Flow, Errors, & Exceptions Flashcards
Which of the following have their own scope?
functions list comprehensions generator comprehensions try-except blocks for + while loops classes
These have their own scope:
functions
list comprehensions
generator comprehensions
classes
These do not have their own scope:
(and hence you can access their variables that are inside the block outside of it)
try-except blocks
for + while loops
Which statement DOES NOT ALLOW you to print ( i ) due to i not being in scope? \_\_\_\_\_ mylist = [i for i in range(5)] print(mylist) print(i)
_____
mylist2 = []
for i in range(5):
mylist2.append(i)
print(mylist2)
print(i)
The former DOES NOT work and i is out of scope:
mylist = [i for i in range(5)]
print(mylist)
print(i)
_____
The latter allows you to reference i outside the block since it is still in scope (loops don’t have scope):
mylist2 = []
for i in range(5):
mylist2.append(i)
print(mylist2)
print(i)
What does ‘break’ do in this statement?
while a < 10: while b < 5: if c == someNumber: break else: ....
‘break’ automatically jumps you out of the innermost loop that you are currently in
(so the inner while loop)
What does ‘pass’ do in this statement?
while a < 10: while b < 5: if c == someNumber: pass else: ....
What does ‘pass’ do in this statement?
‘pass’ automatically jumps to the next iteration of the innermost loop you are currently in
What does ‘pass’ do in this statement?
def some_function(): pass
What does ‘pass’ do in this statement?
‘pass’ automatically allows the function to keep running regardless whether you return a statement or not
What does ‘try-except’ do in the following?
try:
…some code…
except:
…some different code…
If the code in the try block doesn’t work it goes to the code in the except block.
What does ‘try-except’ do in the following?
try:
…some code…
except someExceptionErrorHere:
…some different code…
except someOtherExceptionErrorHere as aliasHere:
…I can reference ‘alias’ here…
…like print(alias)…
…some different code…
except:
…some different code…
If the code in the try block doesn’t work it goes to the code in the first except block if that exception is valid, else it goes to the next except block where you can now reference the error as an alias, and if this except block doesn’t work then you can go to the “catch-all” exception block which is the last one.
How can I use try-except to debug when the following loop fails?
for i in range(5): if someCondition: .... else: ....
I can debug by embedding the for loop in the try block, and printing anything that throws in error in the except block:
try: for i in range(5): if someCondition: .... else: ....
except:
print( f ‘ The loop goes wrong at iteration { i } ‘ )
_____
***notice how I can still reference variable i outside the try block and outside the for loop. That is because try blocks and for loops don’t have a concept of scope.
Is it good practice to use ASSERT statements for program control flow?
How do ASSERT statements work?
No! ASSERTS should be used for debugging only! If you wanna continue having the program run and are just trying to control the flow, use conditionals / loops / breaks / pass / try-excepts…NOT assert statements.
_____
Python has built-in assert statement to use assertion condition in the program. assert statement has a condition or expression which is supposed to be always true. If the condition is false assert halts the program and gives an AssertionError.
Syntax for using Assert in Python:
assert
assert ,
What’s a smart way to use try-except for any possible division error below?
def divide(x, y): return x / y
def divide(x, y): try: return x / y except ZeroDivisionError: if x == 0: return float('NaN') return float('inf')
How would you use try-except to catch different scenarios in the below WITHOUT using multiple except blocks?
Let’s say you want to capture ZeroDivisionErrors and TypeErrors
***Hint: use tuples
def divide(x, y): return x / y
def divide(x, y): try: return x / y except (ZeroDivisionError, TypeError): return 'Error!'
What would the following program output, assuming the user types “abc”? (Note that the options below do not include what the user types)
try: my_number = int(input('Enter number: ')) print(my_number + 1) except ValueError: print('Oh no!')
___ 1 ___
Enter number:
Traceback (most recent call last): File “python”, line 1, in ValueError: invalid literal for int() with base 10: abc
Oh no!
___ 2 ___
Enter number:
Oh no!
___ 3 ___
Enter number:
Oh no!
1
___ 4 ___
Enter number:
Traceback (most recent call last): File “python”, line 1, in ValueError: invalid literal for int() with base 10: abc
try: my_number = int(input('Enter number: ')) print(my_number + 1) except ValueError: print('Oh no!')
___ 2 ___
Enter number:
Oh no!
What does the word ‘raise’ by itself do?
The raise statement allows the programmer to force a specified exception to occur. For example:
> > > raise NameError(‘HiThere’)
Traceback (most recent call last):
File “”, line 1, in
NameError: HiThere
The sole argument to raise indicates the exception to be raised. This must be either an exception instance or an exception class (a class that derives from Exception). If an exception class is passed, it will be implicitly instantiated by calling its constructor with no arguments:
> > > raise ValueError # shorthand for ‘raise ValueError()’
If you need to determine whether an exception was raised but don’t intend to handle it, a simpler form of the raise statement allows you to re-raise the exception to pass back up and outside the code black:
>>> try: ... raise NameError('HiThere') ... except NameError: ... print('An exception flew by!') ... raise ... An exception flew by! Traceback (most recent call last): File "", line 2, in NameError: HiThere
What does the word ‘finally’ do?
A finally clause is always executed before leaving the try statement, whether an exception has occurred or not.
When an exception has occurred in the try clause and has not been handled by an except clause (or it has occurred in an except or else clause), it is re-raised after the finally clause has been executed. The finally clause is also executed “on the way out” when any other clause of the try statement is left via a break, continue or return statement.
>>> try: ... raise KeyboardInterrupt ... finally: ... print('Goodbye, world!') ... Goodbye, world! KeyboardInterrupt Traceback (most recent call last): File "", line 2, in
# This program tries to gracefully handle the case # where the user enters a non-integer. See if you # can fix it!
try:
number = int(input(‘Enter number: ‘))
print(‘You typed: {0}’.format(number))
except IndexError:
print(‘You must enter an integer!’)
try:
number = int(input(‘Enter number: ‘))
print(‘You typed: {0}’.format(number))
except ValueError:
print(‘You must enter an integer!’)
# This program tries to define an exception class # and a function that uses that exception class. # If a negative number is entered, the program # should print the message given as an argument # to the constructor of the exception class. See # if you can fix it!
class NegativeNumberException: pass
def retrieve_non_negative_number():
number = int(input(‘Enter non-negative number: ‘))
if number <= 0:
raise NegativeNumberException(‘The number
cannot be negative!’)
return number
try:
print(retrieve_non_negative_number())
except NegativeNumberException as e:
print(e)
# This program tries to define an exception class # and a function that uses that exception class. # If a negative number is entered, the program # should print the message given as an argument # to the constructor of the exception class. See # if you can fix it!
class NegativeNumberException(Exception): def \_\_init\_\_(self, message): self.message = message
def retrieve_non_negative_number():
number = int(input(‘Enter non-negative number: ‘))
if number < 0:
raise NegativeNumberException(‘The number
cannot be negative!’)
return number
try:
print(retrieve_non_negative_number())
except NegativeNumberException as e:
print(e)
Write a program with a function called retrieve_integer. This function should ask the user for a number. If they enter an integer, return that integer, if they enter a non-integer, your function should print “Uh oh!”. However, the exception should not stop there; it should continue to wherever your function was called! (Consider using the word raise by itself here.)
Your prompt should look like this:
Enter number:
Your submission should include only your function definition.
def retrieve_integer():
try: user_num = int(input('Enter number: ')) return user_num except ValueError: print('Uh oh!') raise
\_\_\_\_ # to test it you can run:
try:
print(retrieve_integer())
except ValueError:
print(‘ValueError caught!’)
Write a program that reads a file called numbers.txt that is supposed to contain only numbers, one per line. However, the file might contain some accidental non-numerical text as well. Your program should ignore the non-numerical lines and print the sum of the numbers it finds.
Say, for example, that numbers.txt contains the following:
1 2 abc 3 4 Your program should output:
10
current_sum = 0
with open('numbers.txt', 'r') as f: for line in f: try: current_sum += int(line) except: pass
print(current_sum)
What are the 5 reserved words you have with exceptions and what do they do?
try: code block that attempts to execute
except: code block(s) which are thrown if there is an error
else: code block that executes after the try statement IF NO exceptions were caught. You can write this after the except blocks.
finally: code block that executes at the end of try block (and after excepts) regardless of whether exception is thrown or not. ***A return statement embedded within either the try/except blocks will always cause the finally block to execute first before the return!
raise: re-throws the exception to capture later (used within the else blocks