
PDSA - Week 1For PythonNumber of operation or instruction when program runsComputing gcdComputing gcd - Eliminate the listComputing gcd - Better WayComputing gcd - Euclid’s algorithmComputing PrimeComputing 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 + b3 return sxxxxxxxxxx51n = int(input())2s = 03for i in range(n):4 s = s + i5print(s)xxxxxxxxxx61def total(n):2 s = 03 for i in range(n):4 for j in range(n):5 s = s + 16 return sIdentify the relationship between number of instructions and input size.
Our Goal - Want to reduce these numbers of instructions when program runs
gcdgcd(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)xxxxxxxxxx61def gcd(m,n):2 cf = [] # List of common factors3 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 listxxxxxxxxxx51def gcd(m,n):2 for i in range(1,min(m,n)+1):3 if (m%i) == 0 and (n%i) == 0:4 mrcf = i5 return(mrcf)Efficiency :- Both versions of gcd take time proportional to min(m, n)
gcd - Better Wayxxxxxxxxxx61def gcd(m,n):2 (a,b) = (max(m,n), min(m,n))3 if a%b == 0:4 return(b)5 else6 return(gcd(b,a-b))Still not efficient, for example gcd(1,1000) takes 1000 steps.
gcd - Euclid’s algorithmxxxxxxxxxx61def gcd(m,n):2 (a,b) = (max(m,n), min(m,n))3 if a%b == 0:4 return(b)5 else6 return(gcd(b,a%b))Can show that this takes time proportional to number of digits in max(m, n)
Prime[1,n]xxxxxxxxxx81def factors(n):2 fl = [] # factor list3 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
xxxxxxxxxx61def primesupto(m):2 pl = [] # prime list3 for i in range(1,m+1):4 if prime(i):5 pl.append(i)6 return(pl)xxxxxxxxxx61def prime(n):2 result = True3 for i in range(2,n):4 if (n%i) == 0:5 result = False6 return(result)xxxxxxxxxx61def prime(n):2 result = True3 for i in range(2,n//2):4 if (n%i) == 0:5 result = False6 return(result)xxxxxxxxxx71def prime(n):2 result = True3 for i in range(2,n):4 if (n%i) == 0:5 result = False6 break # Abort loop7return(result)xxxxxxxxxx81import math2def prime(n):3 (result,i) = (True,2)4 while (result and (i <= math.sqrt(n))):5 if (n%i) == 0:6 result = False7 i = i+18 return(result)
Our code could generate many types of errors
Types of some common errors
SyntaxError: invalid syntaxNameError: name ’x’ is not definedZeroDivisionError: division by zeroIndexError: list assignment index out of rangeHandling exceptions
xxxxxxxxxx101try:2 #... ← Code where error may occur3except (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 = a4 self.y = b5
6 def translate(self,deltax,deltay):7 self.x += deltax8 self.y += deltay9
10 def odistance(self):11 import math12 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
xxxxxxxxxx21(3,4)2(8,12)
xxxxxxxxxx321import time2
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 = None9 self._elapsed_time = None10
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_time22 self._start_time = None23
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
xxxxxxxxxx31import sys2sys.setrecursionlimit(100000)3gcd(2,99999)Calculate time for large value
xxxxxxxxxx51# 10^162t.start()3print(678912345678912345,987654321987654321,gcd(678912345678912345,987654321987654321))4t.stop()5print(t)Example-