0% found this document useful (0 votes)
7 views

Python Programming Debugging

The document discusses coding errors in Python, focusing on syntax errors, logical errors, and exception handling. It explains various built-in exceptions, the importance of exception handling, and the advantages and disadvantages of using it. Additionally, it covers concepts such as assertions, logging, and debugging techniques to improve code reliability and maintainability.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

Python Programming Debugging

The document discusses coding errors in Python, focusing on syntax errors, logical errors, and exception handling. It explains various built-in exceptions, the importance of exception handling, and the advantages and disadvantages of using it. Additionally, it covers concepts such as assertions, logging, and debugging techniques to improve code reliability and maintainability.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 43

Coding Errors in Python-Programming

Syntax Errors

Logical Errors
Syntax Errors
A syntax error is one of the most basic types of error in programming. Whenever
we do not write the proper syntax of the python programming language (or any
other language) then the python interpreter or parser throws an error known as
a syntax error. The syntax error simply means that the python parser is unable to
understand a line of code.

number = 100

if number > 50
print("Number is greater than 50!")
File "test.py", line 3
if number > 50
^
SyntaxError: invalid syntax

Since we have missed the colon (:) after the if statement.


Logical Errors (Runtime Errors)
Logical Errors are those errors that cannot be caught during compilation time.
As we cannot check these errors during compile time, we name
them exceptions. Since we cannot check the logical errors during compilation
time, it is difficult to find them.

number = 100
divided_by_zero = number / 0

print(divided_by_zero)
Traceback (most recent call last):
File "d:\test.py", line 2, in <module>
divided_by_zero = number / 0
ZeroDivisionError: division by zero
Zero Division Error is raised by the Python interpreter when we try to divide any number
by zero.
Exception Handling
Errors that occur at runtime (after passing the syntax test) are called exceptions or

logical errors.
An exception is an unexpected event that occurs during program execution.
For example,
divide_by_zero = 7 / 0
The above code causes an exception as it is not possible to divide a number by 0.

Python Built-in Exceptions


Illegal operations can raise exceptions.
Exceptions give you information like what, why and how something went wrong.
There are plenty of built-in exceptions in Python that are raised when corresponding
errors occur.
Exception Description
As the name suggests, the IndexError is raised when the
IndexError
wrong index of a list is used.
AssertionError AssertionError is raised when the assert statement fails
AttributeError is raised when an attribute assignment is
AttributeError
failed.
ImportError is raised when an imported module is not
ImportError found or there is a problem in importing the required
module.
KeyError is raised when the key of the dictionary is not
KeyError
found.
NameError NameError is raised when the variable is not yet defined.
MemoryError is raised when a program runs out of
MemoryError
memory.
TypeError is raised when a function or an operation is
TypeError
applied in an incorrect type.
EOFError is raised when the input() function hits the
EOFError
condition of end-of-file.
FloatingPointError is raised when a floating-point operation
FloatingPointError
fails.
TypeError is raised when we call the
GeneratorExit
generator's close() method.
KeyboardInterrupt is raised when a user hits the interrupt
KeyboardInterrupt
key i.e. Ctrl+C or Delete.
NotImplementedError is raised by abstract methods when
NotImplementedError
they are defined.
OSError is raised when system operation causes system-
OSError
related errors.
OverflowError is raised when the result of an arithmetic
OverflowError
operation is too large.
ReferenceError is raised when a weak reference proxy is
ReferenceError
used to access a garbage collected referent.

RuntimeError is raised when an error does not fall


RuntimeError under any other category of built-in Python
exceptions.
StopIteration is raised by the iterator's next() function
StopIteration to indicate that there is no further item to be returned
by the iterator.
IndentationError IndentationError is raised when there is incorrect indentation.
TabError TabError is raised when interpreter detects internal error.
SystemError is raised when indentation consists of
SystemError
inconsistent tabs and spaces.
UnboundLocalError is raised when a reference is made to a
UnboundLocalError local variable in a function or method, having no value bound
to that variable.
UnicodeError is raised when a Unicode-related encoding or
UnicodeError
decoding error occurs.
UnicodeEncodeError is raised when a Unicode-related error
UnicodeEncodeError
occurs at the time of encoding.
UnicodeDecodeError is raised when a Unicode-related error
UnicodeDecodeError
occurs at the time of decoding.
UnicodeTranslateError is raised when a Unicode-related
UnicodeTranslateError
error occurs during translating.
ValueError is raised when a function is given the correct type
ValueError
of argument but with an improper value.
ZeroDivisionError is raised when we try to divide any number
ZeroDivisionError
by zero.
Exception Handling
def add(x,y):
return (x+y)

print(add(2,7))
print(add(5,10))
print(add(7,'a'))
print(add(12,2))
print('Execution done')
def add(x,y):
try:
return (x+y)
except TypeError:
return ("Invalid")

print(add(2,7))
print(add(5,10))
print(add(7,'a'))
print(add(12,2))
print('Execution done')
The try block lets you test a block of code for errors.
The except block lets you handle the error.
The else block lets you execute code when there is no error.
The finally block lets you execute code, regardless of the result of the try- and
except blocks.
Try and Multiple Except

try:
print(x)
except NameError:
print("Variable x is not defined")
except:
print("Something else went wrong")
Else Clause

The code enters the else block only if the try clause does not raise an exception.

def divide(x, y):


try:
result = x // y
except ZeroDivisionError:
print("Sorry ! You are dividing by zero ")
else:
print("Yeah ! Your answer is :", result)

divide(3, 2)
divide(3, 0)

Output
Yeah ! Your answer is : 1
Sorry ! You are dividing by zero
Exception handling with try, except, else, and finally
Try: This block will test the excepted error to occur
Except: Here you can handle the error
Else: If there is no exception then this block will be executed
Finally: Finally block always gets executed either exception is generated or not
def divide(x, y):
try:
result = x // y
except ZeroDivisionError:
print("Sorry ! You are dividing by zero ")
else:
print("Yeah ! Your answer is :", result)
finally:
# this block is always executed
# regardless of exception generation.
print('This is always executed')

divide(3, 2)
divide(3, 0)

Yeah ! Your answer is : 1


This is always executed
Output Sorry ! You are dividing by zero
This is always executed
Advantages of Exception Handling
Improved program reliability: By handling exceptions properly, you can prevent
your program from crashing or producing incorrect results due to unexpected
errors or input.
Simplified error handling: Exception handling allows you to separate error
handling code from the main program logic, making it easier to read and
maintain your code.
Cleaner code: With exception handling, you can avoid using complex
conditional statements to check for errors, leading to cleaner and more
readable code.
Easier debugging: When an exception is raised, the Python interpreter prints a
traceback that shows the exact location where the exception occurred, making
it easier to debug your code.
Disadvantages of Exception Handling

Performance overhead: Exception handling can be slower than using conditional


statements to check for errors, as the interpreter has to perform additional work to
catch and handle the exception.
Increased code complexity: Exception handling can make your code more complex,
especially if you have to handle multiple types of exceptions or implement complex
error handling logic.
Possible security risks: Improperly handled exceptions can potentially reveal
sensitive information or create security vulnerabilities in your code, so it’s important
to handle exceptions carefully and avoid exposing too much information about your
program.
Raising Exceptions

Python raises an exception whenever it tries to execute invalid code. Python’s


exceptions were handled with try and except statements so that your program
can recover from exceptions that you anticipated.
But you can also raise your own exceptions in your code.
Raising an exception is a way of saying, “Stop running the code in this function
and move the program execution to the except statement.”
Exceptions are raised to validate the input data.
Exceptions are raised with a raise statement.
Example:

x=int(input("Enter the value for x:"))


y=int(input("Enter the value for y:"))
try:
if y==0:
raise ZeroDivisionError("Divided by zero")
c=x/y
print(c)
except ZeroDivisionError as var:
print (var)
Example:

marks=int(input("Enter the marks:"))


try:
if marks<0 or marks>100:
raise Exception
print("Marks:",marks)
except Exception:
print("Marks should be greater than 0 or less than 100")
Traceback

Whenever the code gets an exception, the traceback will give the information
about what went wrong in the code. The Python traceback contains great
information that can help you find what is going wrong in the code. The
traceback includes the error message, the line number of the line that caused
the error, and the sequence of the function calls that led to the error. This
sequence of calls is called the call stack.
The traceback is displayed by Python whenever a raised exception goes
unhandled.
Example:
mylist = [1, 2, 3]
print(mylist[10])

In this example, we are trying to access the 10th element of the list. With only
3 elements present in the list it will give Runtime error. When this program is
executed you will get the following traceback.

This traceback error has all the information about why this runtime error
occurred. Last line of the traceback tells you about what type of error occurred
along with relevant information. Previous lines of traceback points to the code
in which error occurred.
In python it is best to read traceback from bottom to top.
GREEN BOX shows the what type of error occurred .
BLUE BOX shows the relevant information about error
ORANGE BOX shows traceback statement for recent calls, below The firstRuntime Error:
Traceback (most recent call last):
File “”, line 1, in
ModuleNotFoundError: No module named ‘asdf’ line of each call contains information
like the file name, line number, and module name
RED underlined part shows exact line where exception occurred.
Example:

number = 1

print(numb)
Assertions
Assertion is a programming concept used while writing a code where the user
declares a condition to be true using assert statement prior to running the
module. If the condition is True, the control simply moves to the next line of
code. In case if it is False the program stops running and returns AssertionError
Exception.
Example:

try:
x=1
y=0
assert y != 0, "Invalid Operation"
print(x / y)

# the errror_message provided by the user gets printed


except AssertionError as msg:
print(msg)
import math Example:
def roots(a, b, c):
try:
assert a != 0, "Not a quadratic equation as coefficient of x ^ 2 can't be 0"
D = (b * b - 4 * a*c)
assert D>= 0, "Roots are imaginary"
r1 = (-b + math.sqrt(D))/(2 * a)
r2 = (-b - math.sqrt(D))/(2 * a)
print("Roots of the quadratic equation are :", r1, "", r2)
except AssertionError as msg:
print(msg)
roots(0, 5, -6)
roots(1, 1, 6)
roots(2,12,18)
Logging
Logging is a means of tracking events that happen when some software runs.
Logging is important for software developing, debugging, and running. If you
don’t have any logging record and your program crashes, there are very few
chances that you detect the cause of the problem. And if you detect the cause,
it will consume a lot of time. With logging, you can leave a trail of breadcrumbs
so that if something goes wrong, we can determine the cause of the problem.
When you run an algorithm and want to confirm it is doing what you expected,
it is natural to add some print() statements at strategic locations to show the
program’s state. Printing can help debug simpler scripts, but as your code gets
more and more complex, printing lacks the flexibility and robustness that logging
has.
With logging, you can pinpoint where a logging call came from, differentiate
severity between messages, and write information to a file, which printing cannot
do. For example, we can turn on and off the message from a particular module of
a larger program. We can also increase or decrease the verbosity of the logging
messages without changing a lot of code.
Python Logging Levels

There are five built-in levels of the log message.


Debug: These are used to give Detailed information, typically of interest only when
diagnosing problems.
Info: These are used to confirm that things are working as expected
Warning: These are used as an indication that something unexpected happened, or is
indicative of some problem in the near future
Error: This tells that due to a more serious problem, the software has not been able to
perform some function
Critical: This tells serious error, indicating that the program itself may be unable to
continue running
If required, developers have the option to create more levels but these are sufficient
enough to handle every possible situation.
Each built-in level has been assigned its numeric value.
Debugger
The debugger is a feature of IDLE that allows you to execute your program
one line at a time. The debugger will run a single line of code and then wait
for you to tell it to continue. By running your program “under the debugger”
like this, you can take as much time as you want to examine the values in
the variables at any given point during the program’s lifetime. This is a
valuable tool for tracking down bugs.

Breakpoints
A breakpoint can be set on a specific line of code and forces the debugger to pause
whenever the program execution reaches that line.

You might also like