Python Made Easy (2013)

Chapter 9: Error Handling

 "When someone says: 'I want a programming language in which I need only say what I wish done', give him a lollipop." - Alan J. Perlis

In this chapter you will learn:

 

·  The basics of error handling

·  Different types of errors

·  How to deal with these errors

All programs have errors. It is of the utmost importance that you know how to handle errors, exceptions, and problems and give you a good idea of how to go about fixing those errors should they arise. Error handling is important for usability.

What Is Exception Handling?

Exception handling is the process of handling errors, exceptions and problems. There are a number of different errors that are commonly seen in nearly any program. By default, programs have certain error codes that they will provide to the programmer, depending on what the error is. Of course, you want to make sure that when errors do arise (for both the programmer and the user) that the error messages are descriptive and give some idea of what the issue might be.

Some of the different types of errors and exceptions that you might deal with on a day to day basis include;

Bugs and Human Errors

Bugs and human errors are the most common problems that you willr un into throughout your programming career. Exception handling begins with gaining a deeper understanding of the different types of codes that will be output by the program when it runs into an issue. Here is what an error message might look at.

Traceback (most recent call last):

File "/home/ryan/errortest.py", line 8, in -toplevel-

answer = menu(< I'll snip it here >)

File "/home/ryan/errortest.py", line 6, in menu

return raw_input(question) - 1

TypeError: unsupported operand type(s) for -: 'str' and 'int'

Now, this probably doesn't look too straightforward to programmers that do not have a lot of experience. Python is telling you a number of different things here. Look at this line;

File "/home/ryan/errortest.py", line 8, in -toplevel-

This line gives us some vital information. First of all, it lets us know which file the error occurred within. This is extremely important for larger programs that have a number of different modules. Without this, it would be difficult to determine exactly where the error might be.

It then tells us what line the error is located on. This lets us know the first place we should look for the issue. Keep in mind that the actual issue could come from another line within the code. Perhaps the line the error references is calling a variable that was never defined? There are multiple reasons why an exception could be triggered, and not all of them will be apparent just by looking at a single line of code.

TypeError: unsupported operand type(s) for -: 'str' and 'int'

This lets us know what type of error has been triggered by the system. This can provide clues as to what the issue within the code might be, which makes them quite easy to fix.

Exceptions

The other type of code error outside of human error is known as an exception. One example of an exception would be when you are asking for user input of a number. The code works fine when everything goes as expected. But what would happen if the user accidentally input a letter instead of a number?

Normally, this would cause the program to crash and all unsaved data to be lost. Instead of crashing, we want the program to recognize that the wrong type of data was entered, and re-prompt the user to enter the correct type of data.

Here is an example of how you would go about handling this exception using the ValueError command;

while True:

    try:

         x = int(raw_input("Please enter a number: "))

         break

     except ValueError:

        print "Oops!  That was no valid number.  Try again..."

Exception handling can be successful when using the try statement. There are a number of reasons for this including;

·     The try statement is executed.

·     If there is no exception, the clause is then skipped and the programs executes as would normally be expected.

·     If an exception occurs during the execution of the clause, then the clause is skipped. In this case, if the program generated a“ValueError” exception, the print command would then be executed and the program would prompt the user for input again.

·     If an exception is generated and does not match the“ValueError” exception, it is then passed to outer try statements that might exist. If there are no outer try statements, this is known as an unhandled exception.

Summary

ü       The following points have been covered in this chapter:

·     Exception handling

·     What is exception handling?

·     What are bugs?

·     Human errors

·     Exceptions

·     How to handle exceptions

Conclusion

So, now you've learned the basics of Python. You've learned about and put into practice all of the basic concepts to get you going including data types, decision making statements and loops. Your in a good place to quickly grow your skills. From here on out, you have to challenge yourself! Python is a deep language with quite a bit to learn, but with a basic understanding of the fundamentals the more advanced concepts can come quite easily. If you compare Python with other programming languages you will find that it is easier to understand and coding in the programming language is better too.

Also, remember that you don’t need to have a degree to verify that you know how to code or how to use Python. This guide has given you all the information you need. More so than any other aspect of programming education– experience is your best friend! You can only become a better programmer when you are willing to put in the work and gain experience in the language of your choice. Practice and spend some time on bettering your concepts, basics and skills.

Once your skills in a programming language are sufficient, you will find that transferring that knowledge to another language is much easier. Since Python is one of the easiest programming languages I know, I suggest that most aspiring programmers and beginners start their journey by using this programming language. It shouldn’t take you too long to understand Python provided you are willing to put the time and effort required.

While there are differences between object oriented programming languages (and other languages), they are for the most part very similar, with transferable skills and concepts.

This guide walks you through all of the basic concepts for programming in Python, and is meant to be a guide that helps you to learn the basics and expand your skills.

Python is a rapidly growing language that is used by some of the largest corporations around the world. Python programmers are in high demand, a trend which will continue moving forward. The best part is that you can master this language within a few days. This programming language is an excellent language for anyone wanting to jump into programming right away.


BONUS

INTRODUCTION

Coding is like a game of chess, only grander, and with chances of undoing moves.  Like chess, coding relies on a select set of moves (think statements and functions) and a problem that has to be resolved by playing those moves until the goal is reached.

For new programmers the task of understanding the problem, breaking it down, creating a strategic coding plan, and then playing the statements to process the goal can become daunting.

Given how fast paced the app development process are: with short deadlines, and reliant on agile development with continuous update of project description, coders that write clean codes are the first choice for contractors. Then again, clean and easily readable code is faster to debug.

This guide will hand over various tools, device, and tips that will help you write better and faster code.

As a result, you can spend less time on your code, deliver results faster, gain better reviews and feedback from the clients, and build a more robust portfolio.

Writing Code

Programming is more an art than a rigid science —the reason why so many large projects fail to get off the ground or work. But as with any modern practice, time and a sense of finding scientific rules, has brought to the coding world various tried and tested methods of organizing a code from the beginning. Though accomplished programmers create their own unique methodologies for writing code, new programmers are well advised to begin with some of the more streamlined methodologies.

Some of the prime problems that you can face during that time is deciphering the problem right and starting out in the right direction for your coding journey. Coding is a long journey and problems in anything ranging from missing a coding glitch or not starting out in the right manner can cause serious problems for everything there is to know there.

This section will highlight the various methodologies currently being employed by the programmers and will help you overcome any problems that head your way.

Tested Coding Methodologies

New programmers should be aware of the multiple programming methodologies being employed by programmers. This will save you the trouble of employing absurd methodologies or combining multiple methodologies. Here’s a first aid box for starting to code the right way on your program.

Spaghetti Programming

This is not really a methodology, but result that new programmers achieve with ease —a tangled mess of an original program that goes through multiple modifications to make it work. The programmers start by identifying a problem and creating a simple program for resolving a part of the problem and then moving ahead with multiple modifications. The result is a program without a proper flow, but that somehow works.

Structured Programming

Keep programs organized by dividing your program into three distinct parts:

·        Sequences - Group of commands that the machine could follow consecutively

       Branches — All command groups that have a condition built into them, causing the machine to follow one of several other group commands over others

▪       Loops —  group of commands dedicated to repeating a task indefinitely or a defined number of times

Planning the program beforehand in terms of the sequences, branches, and loops is best suited for short programs.

Top Down Programming

At times programs get lengthier and it becomes difficult to gain a panoramic view of the whole program. When this happens, programmers tend to break the program into multiple blocks, each defined by the function it is supposed to perform. The idea is that writing smaller chunks of programs is easier. You start by identifying the main tasks that your program must perform and then create smaller programs for each task. Finally, you paste them together like building blocks and integrate them in the main. This makes it easier to find and modify sub programs and hence make a better program.

Event - Driven Programming

Programming where the flow is determined by occurrence of events i.e. inputs from the user (touch, mouse clicks, key presses, etc) or inputs received from other threads or programs. Normally the program has a main loop that is divided into two sections: an event detection block and an event handler block. This drastically speeds up the response time of the application being developed.

Object Oriented Programming

Currently popular, when writing a code using this methodology, programmers define not just the data type of a data structure, but also the types of its functions that can be applied to the data structure. As a result, the original data structure becomes a standalone object with data and functions. Later, the programmer can code relationships between two and more objects and build the program using these blocks.

The prime advantage of this programming method is that programmers can continue creating new objects without having to make any change to any module.

MAKING READING SIMPLER –BEST PRACTICES FOR WRITING READABLE CODES

Extensive Documentation

Explain your work.  Add comments inside programming to show what direction you are taking: what a group of commands, or a chunk of code, is meant to do; why you’ve added it in the first place, and more. This makes it easier to read your code and see how each chunk of program connects with the other.

Standardize Indention and Naming Schemes  

Indention makes it easier to skim through a program. It allows the reader to easily differentiate between conditions/loops and the code that is relevant to them or outside of them. Though it is not a requirement of most programming languages, it will allow you to better convey the structure of your programs.

Employing a standard naming scheme for declaring variables, classes, functions, etc, creates symmetry and makes it easier to spot a problem lines away. Two popular choices include using underscores between strings/characters (e.g. first_variable_name), and in case of not leaving spaces, capitalizing the first letter of every word except the first word (e.g. firstVariableName)

Group Codes

Use comments to separate blocks of code, no matter how small. More often than not, a task requires very few lines of code, and hence can become easily lost in the sea of code. To prevent this from happening, simply create separate blocks by adding a space followed by a short comment before the start of the block.

Do No Evil

Often known as the DIE (Duplication is Evil) and DRY (Don’t Repeat Yourself), it is a principle that reminds programmers of the fundamental purpose of writing codes: to automate repetitive tasks. In a phrase, the same piece of code should never be repeated in your code.

Set a Line Limit

Make it easier to read your code. Avoid writing lengthy horizontal codes. Standardize the characters you want for a single line of code then break the line and start in the next. Writing codes in vertical, column like (newspaper like), form makes reading more comfortable for our eyes.

Select the Right Methodology

Nowadays, object oriented programming is a norm for creating well-structured programs. But at times, structured and procedural programming can prove beneficial. A good rule of thumb is to use objects when data representation is involved (e.g. data from a database), whereas, structured programming may be use for tasks that can be performed independently.

SOLOMON ON DEBUGGING –BEST PRACTICES FOR DEBUGGING CODES

The 9 Rules of Debugging

Dave Agans, near legend software developer and holder of various customary titles, once stumbled upon the Wisdom of Solomon (while Solomon was debugging programs). Here are the 9 rules that will get you through any debugging trouble you’re likely to face.

▪       Understand the system

▪       Make it fail

▪       Quit thinking and look

▪       Divide and conquer

▪       Change one thing at a time

▪       Keep an audit trail

▪       Check the p lug

▪       Get a fresh view

▪       If you didn't fix it, it ain't fixed

Let’s see each in brief:

Rule

What You Need to Do

Understand the system

This holds true especially in case you are working with a code that’s running on a specific platform or device.

•       Understand how the system processes the code by thoroughly reading the instruction manual.

•       Know the roadmap for the code. You must know what functions are where and how the coding blocks and interfaces do.

•       Know the tools you’ll be using and how they debug.

Make It Fail

Learn all the instances where the program fails. This lets you focus on hypothesizing for probable causes. It’s like knowing how you can make a sane program generate the same error again.  But don’t rely on this if the problem is intermittent i.e. it happens only once in a while.

In case of intermittent failures, check for uninitialized data, multi-thread synchronization, timing variations, random data input, etc.

Quit thinking and look

The worst thing you can do is to rely on your intuition. Guesswork is a capital mistake. It makes you twist the debugging process to verify or falsify your guesswork. It’s a waste of time, and most of the code you’ve changed will end up creating more trouble later.

•       See the error occur in person

•       Find the details. Don’t guess which code block is the culprit, find the lines.

•       Guess only to focus the research.

Divide and conquer

It’s hard for the bug to remain hidden if its hiding place keeps getting cut in half.

Find the problem by narrowing the search with successive approximation i.e. find the range of possibilities where the bug could have occurred. Start on the worst hit parts and fix the bugs that clearly shout out their presence. Don’t forget to fix the small noisy bugs that make the system go haywire.

Change one thing at a time

Make the process predictable. Remove any changes you made that did not return the expected result. Your task is to isolate the key factor, and understand it before pulling the guns on it.

Keep an Audit Trail

Make not of what did, in the exact order as you did, and what happened when you did it. Always correlate events, and no matter how horrible the moment, note it down.

Check the Plug

Avoid falling into the trap of obvious assumptions. They often prove to be wrong. Always question your assumptions by checking them for bugs in the first place.

Get a fresh view

Take a break. Don’t shy away from asking for help or asking for insights from others. Bugs happen, and your task should be to take pride in getting rid of them, and not “getting rid of them yourself!”

If you didn't fix it, it ain't fixed

Test and retest, and verify if it’s really fixed. Keep in mind that a bugnever goes away on its own. If you think you’ve fixed it, take out the audit book and make it fail like it never went away yourself.

The 80/20 Rule

80% of the results come from 20% of effort and 80% of effects come from 20% of causes. Period.

The 80/20 rule states that 80% of the results come from 20% of the causes, and 20% of the results come from 80% of the causes. This rule is also known as the Pareto principle.

Various examples of this rule are floating around the marketplace. Here are the ones that relate to the development process:

▪                                                                                                          80% of the code is running 20% of the runtime.

▪       20% of the code is running 80% of the runtime.

This means that whatever code you have with you right now, and which needs debugging, has a small part that is running most of the time, but a bigger chunk of it that is nor running all the time.

Coding Lesson: You should not assume that debugging, or project’s progress, is ever linear.

[EXAMPLE]

Become Disciplined

Approach debugging as a process, and not a series of random trial and error steps. You can’t count on your luck by tweaking some knobs in the code and hope to stumble on the bug. Rather, make it a habit to follow the code’s execution process. Is the first block getting the input that it needs to produce an output for block B? Yes?, move on. No? Start digging.

Debug Other People’s Code

Coding is like communicating your opinionated solutions to a problem. It always has some assumptions, and which most likely causes errors to occur. If you find yourself stuck at debugging your own code, take a whiff of someone else’s code (think cross-peer debugging and cross-peer code reviews). By debugging someone else’s code, it  becomes easier to figure out assumptions that other people have made. This in turn can bring to light some of the ones that you had left out during your debugging process. Furthermore, peer-review debugging sharpens your ability to pinpoint common causes of defects more quickly, and as a result teaches you to recognize (and abandon) your own bad development practices.

Think like a Compiler

This is something that must be done before you hit the compile button. This is an exercise in correcting as many errors before you let the IDE’s integrated debugger to create the program. The fact of the matter is that you’ll learn less from compiler’s automation whereas by consciously examining the process will give you more depth to the basic debugging process, and hence common errors.

Debug the System and not Part of Blocks of Code

It’s a mistake to start debugging by focusing only on part the code. Always pay attention to the interrelationships between modules, which is only possible if you have internalized the “9 rules of debugging”mentioned earlier. A rule of thumb is to read the code at multiple levels of abstraction i.e. spend time understanding what multiple pieces of the code are actually doing together.

CODE BLUNDERS –AVOIDING THE FATAL MISTAKES

Over the years, programmers have come to acknowledge some common mistakes that brings home the message: it’s not about how accomplished you are. Here are the top 8 mistakes that are made often and which can trouble your to no end:

Undeclared Variables

int main()

{

  cin>>b;

  cout<<b;

}

In the above code, the variable “b”has not been declared. There is no memory location for that variable, and hence, the compiler cannot send or fetch information from the location “b”. This is rectified in the code below:

int main()

{

  int b;

  cin>>b;

  cout<<b;

}

Uninitialized Variables

Not all languages automatically initialize a declared variable to zero e.g. C++

int variable;

while(variable<100)

{

  cout<<variable;

  variable++;

}

The above program will not enter the loop because the integer variable has not been assigned a fixed initial value.

Hence the program would print all numbers within int range. Always remember to initialize your variables.

int variable =0;

while(variable<100)

{

  cout<<variable;

  variable++;

}

Assigning a Variable to an Uninitialized Variable

Look at the code below where two integers are added

int y, z;

int add=y+z;

cout<<"Enter the two numbers you want to add: ";

cin>>y;

cin>>z;

cout<<"The answer is: "<<add;

The result of this program will be garbage values because the compiler does not know the basic equations like we do. Once you have assigned a value to a variable, that value remains till the end of times unless you reassign them. In the example program, because and z are not initialized,add will always equal some unknown number no matter what number you decide to input. 

Here’s the fixed code:

int y, z;

int add; //initialized//

cout<<"Enter the two numbers you want to add: ";

cin>>y;

cin>>z;

sum=y+z;

cout<<"The answer is: "<<add;

Undeclared Functions

int main()

{

  something();

}

void something()

{

  //...

}

What is something? Unknown error.

You’re assuming that the compiler will dig out information on what and who menu() is. It won’t, not unless you declare it yourself. Always remember, either enter a prototype for a function, or define it in full above before the first time you give a run for the memory.

void something();

int main()

{

  something();

}

void something()

{

  ...

}

Will know what something is like it’s best bud.

Adding Extra Semicolons

int trying;

for(trying=0;trying<100;trying++);

  cout<<trying;

Output is 100. Always.

Semicolons have no place after loops, if statements, and/or definitions of functions.

int trying;

for(trying=0; trying<100; trying++)

  cout<<trying;

Overstepping Your Array Boundaries

There are limits that you must never cross:

int array[25];

//...

for(int boundaries=1; boundaries<=10; x++)

  cout<<array[boundaries];

Where are correct values? Lost in the digital void…

Arrays begin indexing at 0 and they always end their indexing at length-1. Period.  Hence if you place a 25 element array, then the first position is at zero and the last one is at 24. So if you want to see your buddy “25”:

int array[25];

//...

for(int boundaries=0; boundaries<10; boundaries++)

  cout<<array[boundaries];

Misusing the operators: || and &&

int value;

do

{

  //...

  record= 27;

}while(!(record==27) || !(record==43))

This code makes the program loop round like a record baby…

The only time that the while loop in the above can be wrong is when both record==27 and record==43 are true, and as a result cause the negation of each to be false i.e. making the || operation return false.

The code above offers a tautology: it is always true because the record can never hold both the values at the same time. Hence, if the program was suppose to only loop  when the value entered for record  was neither 27 nor 43, then it is necessary to use:

&& : !(record==27) && !(record==43).

This means "if record is not equal to 27 and record is also not equal to 43".

Programmers often mistake this logic by stating it as it is "this" or "that", while completely ignoring that the "other than"  also applies to the entire statement and the two terms individually. This means you need to revisit the basics of Boolean algebra here!

No matter, the proper way to write the program is as follows:

int record;

do

{

  //...

  record=27;

}while(!(record==27) && !(record==43))

WHAT EVERY PROGRAMMER/CODER MUST HAVE

Tools for Boosting Productivity

Tool

Function

WorkRave

Programming is “all-consuming”and it’s easy to get caught up in the work. Though not a bad thing, working all day on a computer can start affecting your health and well-being.  WorkRave forces you to take mini-breaks for your eyes and wrists. After a set time period, the program reminds you to give yourself a rest, grab a coffee, take a stroll, or any other non-computer related task.

Blinklist

A real computer geek is rarely satisfied with only one computer. True that, but syncing multiple machines is a pain. Blinklist makes it easier to share bookmarks as well as note from anywhere.

CCleaner

Make your computer a lean mean development machine with this gig. Using your computer for extended periods can lead to accumulation of a lot of junk. It slows it down. CCleaner is the software that keeps your computer registry and other useless space hogging programs. Being on your computer all the time can lead to the accumulation of a lot of junk that can slow you down.

EditPad Pro

It’s hard to imagine a programmer who has not relied on the Notepad to do some of their work. After all, it’s simple and gets the job done. EditPad Pro kicks the functionality several notches up. It grants you the ability to switch between files using tabs. It also offers a kind of “back in time”feature that lets you return to your previous editing position. Never lose your place with this tool!

Filezilla

FTP is an incredibly useful tool for uploading websites and sharing files. Filezilla is your free FTTP tool offering standard features like drag and drop, resume, among support for a variety of transfer protocols.

Inspector File Recovery

It happens to even the best of us: we’re working happily on a project and forget to save a file, or horrifyingly “SHIFT + DELETE”and later realize how important it was. Inspector File Recovery is the answer to all such day-mares and nightmares. This program can bring the files from the depths of the recycle bin even when your boot sector is damaged and headers are missing. Save your heart the shock and download it today!

KeePass

Forget your passwords? Perhaps because you have so many of them? KeePass makes brain cramps of such a thing of the past. It can keep track of all your passwords and make it easier to remember just one password.

MediaMax

No matter how many terabytes you have on your computer, you can’t call it unlimited, or even risk free. Give yourself a storage boost of up to 25 GB with MediaMax, a free web-based app called MediaMax.

Plaxo

Keep your contact information updated and synched on all your smart devices with Plaxo. It automatically updates any contact information that you update in your email client by storing it (and updating it) on Plaxo’s servers.

Ta-Da List

Staying orderly when the programs wont debug the right way can become challenging even for the most diligent of workers. Ta-Da List helps you out by keeping all your written tasks in order and accessible from any computer you use.

Tools for Better Project Management

Tool

Function

Wunderlist

A wonderfully simple and basic task management and to-do list application. It allows you to create multiple to-do lists, create detailed tasks, add reminders, and more. It also allows you to sync your tablets, smartphones, laptops, and PCs. The paid pro tier allows addition of sub-tasks, emailing/printing, and sharing tasks to other workers.

Remember the Milk

Another basic task management app that offers extensive online support through their website as well as iOS, Android, and Blackberry apps. You can easily integrate it with your existing Twitter, Gmail, and Outlook accounts as well as Evernote and Google Calendar.

The app will remind you through email, instant messages, and texts about your priorities and tasks. Furthermore, you can even share the tasks or decide to manage them offline as well.

Toodledo

This is a full feature task management app with hotlist features for determining your high priority tasks, fine tuning of your tasks, and multiple filters, and a robust scheduler for planning your days (alarm included)

Producteev

This offers a big picture view of your tasks. It is a good solution if you need to manage tasks for multiple people but are not ready for a full-blown management software. Create teams and assign tasks and deadline; add notes, track progress, and various other options to gain a panoramic view of the entire process.

Google Tasks

This service streamlines task management and is best suited if you are heavily reliant on Gmail or Google Calendar in your day to day workflow. Tasks adds a task list to your Gmail. It’s easily accessible, and lets you convert emails into tasks as well as import new tasks into Google Calendar.

WHAT EVERY PROGRAMMER MUST KNOW

The Programmer’Bill of Rights

Experts have long concluded that working conditions that are normally available for programmers, no matter how high their salary package is, cripple them. Hence, Jeff Atwood, coder and programmer incarnate brought the coding world a preposition for adopting a Bill of Rights for programmers. It includes things that programmers must not be denied:

       Every programmer shall have a fast PC

       Every programmer shall have two monitors

       Every programmer shall have their choice of mouse and keyboard

       Every programmer shall have a comfortable chair

       Every programmer shall have a fast internet connection

       Every programmer shall have quiet working conditions

Programming requires focused mental concentration. Programmers cannot work effectively in an interrupt-driven environment. Make sure your working environment protects your programmers' flow state, otherwise they'll waste most of their time bouncing back and forth between distractions.