Michael Ernst CSE 140 University of Washington

Slides:



Advertisements
Similar presentations
Detecting Bugs Using Assertions Ben Scribner. Defining the Problem  Bugs exist  Unexpected errors happen Hardware failures Loss of data Data may exist.
Advertisements

Interactive Media and Game Development Debugging.
Debugging Introduction to Computing Science and Programming I.
Debugging CPSC 315 – Programming Studio Fall 2008.
Debugging CMSC 201. Announcements Hw2, Hw3 grades returned if something doesn’t seem right, ask Midterm next Thurs (Oct 23) we’ll review on Tues no hw.
ICAPRG301A Week 4Buggy Programming ICAPRG301A Apply introductory programming techniques Program Bugs US Navy Admiral Grace Hopper is often credited with.
General Programming Introduction to Computing Science and Programming I.
Testing Michael Ernst CSE 140 University of Washington.
Testing CSE 140 University of Washington 1. Testing Programming to analyze data is powerful It’s useless if the results are not correct Correctness is.
Errors And How to Handle Them. GIGO There is a saying in computer science: “Garbage in, garbage out.” Is this true, or is it just an excuse for bad programming?
Chapter 22 Developer testing Peter J. Lane. Testing can be difficult for developers to follow  Testing’s goal runs counter to the goals of the other.
Debugging and Interpreting Exceptions UW CSE 190p Summer 2012.
Testing and Debugging Session 9 LBSC 790 / INFM 718B Building the Human-Computer Interface.
Debugging Strategies from Software Carpentry. Agan's Rules Many people make debugging harder than it needs to be by: Using inadequate tools Not going.
Making Good Code AKA: So, You Wrote Some Code. Now What? Ray Haggerty July 23, 2015.
Fixing the Defect CEN4072 – Software Testing. From Defect to Failure How a defect becomes a failure: 1. The programmer creates a defect 2. The defect.
Error messages 25-Apr-17.
Testing CSE 160 University of Washington 1. Testing Programming to analyze data is powerful It’s useless (or worse!) if the results are not correct Correctness.
PROGRAMMING IN PYTHON LETS LEARN SOME CODE TOGETHER!
The single most important skill for a computer programmer is problem solving Problem solving means the ability to formulate problems, think creatively.
Debugging Ruth Anderson UW CSE 160 Winter
JavaScript Introduction and Background. 2 Web languages Three formal languages HTML JavaScript CSS Three different tasks Document description Client-side.
Interpreting Exceptions UW CSE 160 Spring 2015 download examples from the calendar 1.
Chapter 13 Debugging Strategies Learning by debugging.
CSC 108H: Introduction to Computer Programming
FOP: Multi-Screen Apps
Introduction to Computing Science and Programming I
CMPT 120 Topic: Python’s building blocks -> More Statements
Introduction to Python
Introduction to Python
COSC 1306 COMPUTER SCIENCE AND PROGRAMMING
Testing and Debugging.
Testing UW CSE 160 Winter 2017.
Presented By S.Yamuna AP/IT
Swapping Segmented paging allows us to have non-contiguous allocations
C ODEBREAKER Class discussion.
Create login screen Decide how you want you log in screen to work. I have 3 examples of different difficulty/approach, but you should have your own ideas.
Introduction to Events
Sentinel logic, flags, break Taken from notes by Dr. Neil Moore
Testing UW CSE 160 Spring 2018.
Ruth Anderson UW CSE 160 Winter 2017
Writing Functions( ) (Part 5)
Writing Functions( ) (Part 5)
Designing and Debugging Batch and Interactive COBOL Programs
Ruth Anderson UW CSE 160 Winter 2017
Sentinel logic, flags, break Taken from notes by Dr. Neil Moore
Ruth Anderson CSE 140 University of Washington
Testing UW CSE 160 Winter 2016.
CSCE 315 – Programming Studio, Fall 2017 Tanzir Ahmed
Ruth Anderson UW CSE 160 Spring 2018
Coding Concepts (Basics)
CSE 403 Lecture 17 Coding.
Exceptions.
EECS150 Fall 2007 – Lab Lecture #4 Shah Bawany
Python programming exercise
Debugging EECS150 Fall Lab Lecture #4 Sarah Swisher
Debugging “Why you were up till 2AM”
Problems Debugging is fine and dandy, but remember we divided problems into compile-time problems and runtime problems? Debugging only copes with the former.
Debugging EECS150 Fall Lab Lecture #4 Sarah Swisher
Recursion Taken from notes by Dr. Neil Moore
CISC101 Reminders All assignments are now posted.
Tonga Institute of Higher Education IT 141: Information Systems
CISC101 Reminders Assignment 3 due next Friday. Winter 2019
Tonga Institute of Higher Education IT 141: Information Systems
CSC 143 Java Errors and Exceptions.
The Troubleshooting theory
Computer Science 340 Software Design & Testing
Debugging UW CSE 160.
Functions, Procedures, and Abstraction
Presentation transcript:

Michael Ernst CSE 140 University of Washington Debugging Michael Ernst CSE 140 University of Washington

What you want your program to do The problem Not the same! ☹ Your goal is to understand what the program is doing and to make these two things the same. What you want your program to do What your program does

Debugging tools Python error message assert print Python interpreter Python Tutor (http://pythontutor.com) Python debugger Best tool: For each of these, discuss how it can be useful. Another good strategy: take a break. The debugger: It’s very useful, but has a steep learning curve. If you end up doing a lot of Python programming, it’s essential. For this class, it’s optional.

Two key ideas The scientific method Divide and conquer If you master those, you will find debugging easy, and possibly enjoyable

The scientific method Create a hypothesis Design an experiment to test that hypothesis Ensure that it yields insight Understand the result of your experiment If you don’t understand, then possibly suspend your main line of work to understand that Tips: Be systematic Never do anything if you don't have a reason Don’t just flail Random guessing is likely to dig you into a deeper hole Don’t make assumptions (verify them)

Example experiments An alternate implementation of a function Run all your test cases afterward A new, simpler test case Examples: smaller input, or test a function in isolation Can help you understand the reason for a failure

Your scientific notebook Record everything you do Specific inputs and outputs (both expected and actual) Specific versions of the program If you get stuck, you can return to something that works You can write multiple implementations of a function What you have already tried What you are in the middle of doing now This may look like a stack! What you are sure of, and why Your notebook also helps if you need to get help or reproduce your results

Read the error message First function that was called (<module> means the interpreter) Traceback (most recent call last): File "nx_error.py", line 41, in <module> print friends_of_friends(rj, myval) File "nx_error.py", line 30, in friends_of_friends f = friends(graph, user) File "nx_error.py", line 25, in friends return set(graph.neighbors(user))# File "/Library/Frameworks/…/graph.py", line 978, in neighbors return list(self.adj[n]) TypeError: unhashable type: 'list' List of all exceptions (errors): http://docs.python.org/2/library/exceptions.html#bltin-exceptions Two other resources, with more details about a few of the errors: http://inventwithpython.com/appendixd.html http://www.cs.arizona.edu/people/mccann/errors-python Second function that was called Call stack or traceback Last function that was called (this one suffered an error) The error message: daunting but useful. You need to understand: the literal meaning of the error the underlying problems certain errors tend to suggest

Divide and conquer Where is the defect (or “bug”)? Your goal is to find the one place that it is Finding a defect is often harder than fixing it Initially, the defect might be anywhere in your program It is impractical to find it if you have to look everywhere Idea: bit by bit reduce the scope of your search Eventually, the defect is localized to a few lines or one line Then you can understand and fix it 4 ways to divide and conquer: In the program code In test cases During the program execution During the development history

Divide and conquer in the program code Localize the defect to part of the program e.g., one function, or one part of a function Code that isn’t executed cannot contain the defect 3 approaches: Test one function at a time Add assertions or print statements The defect is executed before the failing assertion (and maybe after a succeeding assertion) Split complex expressions into simpler ones Example: Failure in result = set({graph.neighbors(user)}) Change it to nbors = graph.neighbors(user) nbors_set = {nbors} result = set(nbors_set) The error occurs on the “nbors_set = {nbors}" line

Divide and conquer in test cases Your program fails when run on some large input It’s hard to comprehend the error message The log of print statement output is overwhelming Try a smaller input Choose an input with some but not all characteristics of the large input Example: Unicode characters, duplicates, zeroes in data, …

Divide and conquer in execution time via print (or “logging”) statements A sequence of print statements is a record of the execution of your program The print statements let you see and search multiple moments in time Print statements are a useful technique, in moderation Be disciplined Too much output is overwhelming rather than informative Remember the scientific method: have a reason (a hypothesis to be tested) for each print statement Don’t only use print statements

Divide and conquer in development history The code used to work (for some test case) The code now fails The defect is related to some line you changed This is useful only if you kept a version of the code that worked (use good names!) This is most useful if you have made few changes Moral: test often! Fewer lines to compare You remember what you were thinking/doing recently

A metaphor about debugging If your code doesn’t work as expected, then by definition you don’t understand what is going on. You’re lost in the woods. You’re behind enemy lines. All bets are off. Don’t trust anyone or anything. Don’t press on into unexplored territory -- go back the way you came! (and leave breadcrumbs!) You’re trying to “advance the front lines,” not “trailblaze”

The game is to go from “working to working” My Favorite Time-Saving Trick: Make Sure you’re Debugging the Right Problem The game is to go from “working to working” When something doesn’t work, STOP! It’s wild out there! FIRST: go back to the last situation that worked properly. Rollback your recent changes and verify that everything still works as expected. Don’t make assumptions – by definition, you don’t understand the code when something goes wrong, so you can’t trust your assumptions. You may find that even what previously worked now doesn’t Perhaps you forgot to consider some “innocent” or unintentional change, and now even tested code is broken

A bad timeline A works, so celebrate a little Now try B B doesn’t work Change B and try again …

A better timeline A works, so celebrate a little Now try B B doesn’t work Rollback to A Does A still work? Yes: Find A’ that is somewhere between A and B No: You have unintentionally changed something else, and there’s no point futzing with B at all! These “innocent” and unnoticed changes happen more than you would think! You add a comment, and the indentation changes. You add a print statement, and a function is evaluated twice. You move a file, and the wrong one is being read You’re on a different computer, and the library is a different version

Once you’re on solid ground you can set out again Once you have something that works and something that doesn’t work, it’s only a matter of time You just need to incrementally change the working code into the non-working code, and the problem will reveal itself. Variation: Perhaps your code works with one input, but fails with another. Incrementally change the good input into the bad input to expose the problem.

Simple Debugging Tools print shows what’s happening whether there’s a problem or not does not stop execution assert Raises an exception if some condition is not met Does nothing if everything works Example: assert len(rj.edges()) == 16 Use this liberally! Not just for debugging! raw_input Stops execution (Designed to accept user input, but I rarely use it for this.)