Download presentation
Presentation is loading. Please wait.
Published byRafe Todd Modified over 6 years ago
1
COMP280:Introduction to Software Development Week 12, Lecture 34
Bernhard Pfahringer
2
Common errors Off-by-one errors Misunderstood scoping rules
Integer division Modifying-while-iterating In-place modification vs. assignment Memory leaks
3
Off-by-one error Most languages use zero-based indexing, but not all.
Avoid indexing, when directly iterating is possible. Instead of: i = 0 while i < len(a): print(a[i]) i+=1 use: for item in a: print(item) If you need the index as well, consider enumerate: for i, item in enumerate(a): print(i, item) Have unit tests that check boundary cases.
4
Misunderstood scoping rules
alist = [1,2,3] def add_works(item): alist.append(item) def add_fails(item): alist += [item] Both are bad style, better use: def add_item(item, alist):
5
Integer division Integer division, modulus computation, especially for negative numbers, may differ between languages. E.g. in Python: >>> 5//2 2 >>> 5.0//2 2.0 >>> -5//2 -3 Therefore: -(5//2) != -5//2
6
Modifying while iterating
alist = [-2, -1, 0, 1, 2] for i in range(len(alist)): if alist[i] > 0: del alist[i] Generate a copy instead, and reassign, if needed: alist = list(filter(lambda x: x <= 0, alist)) Or, using list comprehension: alist = [x for x in alist if x <= 0]
7
Confusing deep and shallow copies
>>> alist = [[0]] * 3 >>> alist [[0], [0], [0]] >>> alist[0].append(1) ?
8
Memory leaks Even in managed languages, ie. garbage-collected ones (C#,Java, …) But with fewer failure patterns Generally: keeping references to object for too long, or forever, Set (global) references to “None” if no longer needed: >>> reference_to_large_object = None May be impossible for (global) mappings or caches, use weak references from library “weakref.py” A weak reference is ignored by the garbage collector -> Objects only pointed to by weak references can be GCed
9
Debugging in general Can be very frustrating and time-consuming, esp. if bugs only occur in long, large memory runs (eg. in server code) Try to isolate the problem, fail fast: simplest input that still causes the bug Add Print statements [frowned upon] Use a debugger (e.g. pdb) to understand your code’s dynamics Maybe do a(n informal) code review Bug found: add a Unit test, to not re-introduce the same bug in the future [Python specific: ]
10
Pdb: Python’s low-level debugger
Allows you to: Step through execution of code Set break points to stop execution at “points of interest” Inspect variable values and also change them Command line based, can be used remotely Good IDEs would have GUI versions built-in Similar tools exist for every programming language [First rule of debugging: Don’t ]
11
Pdb cont. 3 ways of using Pdb: Commands:
Running some command: pdb.run(…) Have explicit break points: pdb.set_trace() anywhere in your code After an error/exception: pdb.pm() for a post-mortem analysis Commands: ? ? Pdb u(p), d(own) the call stack l(ist) to see current code Locals() for all local values s(tep) and n(ext) to go through code 1-by-1 r(eturn) to exit current function c(ontinue) to go on Also: set breakpoints, etc.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.