PDSA - Week 1For PythonNumber of operation or instruction when program runsComputing gcd
Computing gcd
- Eliminate the listComputing gcd
- Better WayComputing gcd
- Euclid’s algorithmComputing Prime
Computing Primes- Other approachComputing Primes- Sufficient to check factors up to √ nException handlingClasses and objectsTimerWhy Efficiency?
Count the number of operation or instruction executed when program runs.
1def total(a,b):
2 s = a + b
3 return s
xxxxxxxxxx
51n = int(input())
2s = 0
3for i in range(n):
4 s = s + i
5print(s)
xxxxxxxxxx
61def total(n):
2 s = 0
3 for i in range(n):
4 for j in range(n):
5 s = s + 1
6 return s
Identify the relationship between number of instructions and input size.
Our Goal - Want to reduce these numbers of instructions when program runs
gcd
gcd(m, n)
— greatest common divisor
gcd(8, 12)
= 4gcd(18, 25)
= 1Also hcf
— highest common factor
gcd(m, n)
always exists Computing gcd(m, n)
gcd(m, n) ≤ min(m, n)
min(m, n)
xxxxxxxxxx
61def gcd(m,n):
2 cf = [] # List of common factors
3 for i in range(1,min(m,n)+1):
4 if (m%i) == 0 and (n%i) == 0:
5 cf.append(i)
6 return(cf[-1])
gcd
- Eliminate the listxxxxxxxxxx
51def gcd(m,n):
2 for i in range(1,min(m,n)+1):
3 if (m%i) == 0 and (n%i) == 0:
4 mrcf = i
5 return(mrcf)
Efficiency :- Both versions of gcd
take time proportional to min(m, n)
gcd
- Better Wayxxxxxxxxxx
61def gcd(m,n):
2 (a,b) = (max(m,n), min(m,n))
3 if a%b == 0:
4 return(b)
5 else
6 return(gcd(b,a-b))
Still not efficient, for example gcd(1,1000)
takes 1000 steps.
gcd
- Euclid’s algorithmxxxxxxxxxx
61def gcd(m,n):
2 (a,b) = (max(m,n), min(m,n))
3 if a%b == 0:
4 return(b)
5 else
6 return(gcd(b,a%b))
Can show that this takes time proportional to number of digits in max(m, n)
Prime
[1,n]
xxxxxxxxxx
81def factors(n):
2 fl = [] # factor list
3 for i in range(1,n+1):
4 if (n%i) == 0:
5 fl.append(i)
6 return(fl)
7def prime(n):
8 return(factors(n) == [1,n])
Counting primes
xxxxxxxxxx
61def primesupto(m):
2 pl = [] # prime list
3 for i in range(1,m+1):
4 if prime(i):
5 pl.append(i)
6 return(pl)
xxxxxxxxxx
61def prime(n):
2 result = True
3 for i in range(2,n):
4 if (n%i) == 0:
5 result = False
6 return(result)
xxxxxxxxxx
61def prime(n):
2 result = True
3 for i in range(2,n//2):
4 if (n%i) == 0:
5 result = False
6 return(result)
xxxxxxxxxx
71def prime(n):
2 result = True
3 for i in range(2,n):
4 if (n%i) == 0:
5 result = False
6 break # Abort loop
7return(result)
xxxxxxxxxx
81import math
2def prime(n):
3 (result,i) = (True,2)
4 while (result and (i <= math.sqrt(n))):
5 if (n%i) == 0:
6 result = False
7 i = i+1
8 return(result)
Our code could generate many types of errors
Types of some common errors
SyntaxError: invalid syntax
NameError: name ’x’ is not defined
ZeroDivisionError: division by zero
IndexError: list assignment index out of range
Handling exceptions
xxxxxxxxxx
101try:
2 #... ← Code where error may occur
3except (IndexError):
4 #... ← Handle IndexError
5except (NameError,KeyError):
6 #... ← Handle multiple exception types
7except:
8 #... ← Handle all other exceptions
9else:
10 #... ← Execute if try runs without errors
Abstract datatype
Class
Object
Example
x1class Point:
2 def __init__(self,a=0,b=0):
3 self.x = a
4 self.y = b
5
6 def translate(self,deltax,deltay):
7 self.x += deltax
8 self.y += deltay
9
10 def odistance(self):
11 import math
12 d = math.sqrt(self.x*self.x +
13 self.y*self.y)
14 return(d)
15
16 def __str__(self):
17 return('('+str(self.x)+','
18 +str(self.y)+')')
19
20 def __add__(self,p):
21 return(Point(self.x + p.x,
22 self.y + p.y))
23
24p = Point(3,4)
25q = Point(5,8)
26print(p)
27print(p+q)
Output
xxxxxxxxxx
21(3,4)
2(8,12)
xxxxxxxxxx
321import time
2
3class TimerError(Exception):
4 """A custom exception used to report errors in use of Timer class"""
5
6class Timer:
7 def __init__(self):
8 self._start_time = None
9 self._elapsed_time = None
10
11 def start(self):
12 """Start a new timer"""
13 if self._start_time is not None:
14 raise TimerError("Timer is running. Use .stop()")
15 self._start_time = time.perf_counter()
16
17 def stop(self):
18 """Save the elapsed time and re-initialize timer"""
19 if self._start_time is None:
20 raise TimerError("Timer is not running. Use .start()")
21 self._elapsed_time = time.perf_counter() - self._start_time
22 self._start_time = None
23
24 def elapsed(self):
25 """Report elapsed time"""
26 if self._elapsed_time is None:
27 raise TimerError("Timer has not been run yet. Use .start()")
28 return(self_elapsed_time)
29
30 def __str__(self):
31 """print() prints elapsed time"""
32 return(str(self._elapsed_time))
Set recursion limit
xxxxxxxxxx
31import sys
2sys.setrecursionlimit(100000)
3gcd(2,99999)
Calculate time for large value
xxxxxxxxxx
51# 10^16
2t.start()
3print(678912345678912345,987654321987654321,gcd(678912345678912345,987654321987654321))
4t.stop()
5print(t)
Example-