Strategies for debugging

-Print out intermediate information

-Commenting code liberally

-Name variables descriptively

-Test early - try to break

-Modularity - separate program into functions that do specific things, and can be tested separately

-First solve an easier case

-Explaining code to someone else

-"Rubber ducky" debugging

In [ ]:
# CHALLENGE: compute gcd(49,28) on paper using Euclidean algorithm
In [1]:
# CHALLENGE: write my_gcd function
def my_gcd(a,b):
    "Returns gcd(a,b), where a,b are non-negative integers."
    if a<b:
        a,b = b,a # swap a,b if a<b
    # Now we can assume that a>=b (since made swap above otherwise)
    if b==0:
        return a 
    return my_gcd(a%b, b)
In [2]:
my_gcd(24,39)
Out[2]:
3
In [3]:
my_gcd(49,28)
Out[3]:
7
In [5]:
my_gcd(18,1)
Out[5]:
1
In [21]:
%%time
my_gcd(2^800+3^812,2^865 -3^500)
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 1.03 ms
Out[21]:
1
In [24]:
%%time
# built-in gcd function is a bit better (doesn't run in to "maximum recursion depth" issue)
gcd(2^1273128-1, 3^1281273-1)
CPU times: user 375 ms, sys: 0 ns, total: 375 ms
Wall time: 385 ms
Out[24]:
13
In [ ]:
# upshot: Euclidean algorithm is very fast, even for big numbers
# compare to factorization method, using builtin factor() function 
In [1]:
# can compute gcd by computing both factorizations
factor(24),factor(39)
Out[1]:
(2^3 * 3, 3 * 13)
In [31]:
%%time
factor(2^137-1)
CPU times: user 187 ms, sys: 15 ms, total: 202 ms
Wall time: 204 ms
Out[31]:
32032215596496435569 * 5439042183600204290159
In [ ]:
# below takes too long
factor(2^547-1)
In [ ]:
# factorization algorithm is much slower than Euclidean algorithm