0% found this document useful (0 votes)
8 views6 pages

F.3 Computer Literacy Python Coding - Lesson 9: Range

The document outlines two search algorithms: Linear Search and Binary Search, detailing their methods and implementations in Python. Linear Search examines each element sequentially, while Binary Search efficiently narrows down the search range in sorted data. It also includes exercises to implement a binary search for User IDs in a list of tuples and modify existing Python files accordingly.

Uploaded by

EricXIze
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views6 pages

F.3 Computer Literacy Python Coding - Lesson 9: Range

The document outlines two search algorithms: Linear Search and Binary Search, detailing their methods and implementations in Python. Linear Search examines each element sequentially, while Binary Search efficiently narrows down the search range in sorted data. It also includes exercises to implement a binary search for User IDs in a list of tuples and modify existing Python files accordingly.

Uploaded by

EricXIze
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

F.

3 Computer Literacy
Python coding - Lesson 9

Objectives:
● Linear Search algorithm
● Binary Search algorithm on sorted data

Concept
Given a list of data, one common task is to locate the data in the list that satisfies some conditions.

e.g. Consider a list of tuples, where each element of the list has the components (User ID, Age,
Height) as in the case of the last assignment:

alst = [ (1483150,59,155), (1414808,22,176), (1412830,16,173), (1441003,52,144),


(1475288,34,174), (1491639,40,127), (1461606,52,131), (1456042,57,132) ]

One might want to find the Age and Height of a user with a given User ID, say 1491639. This is
searching.

Linear Search
If the list of data has no specific order, as the above example has shown, then the searching must be
done by examining each element one by one, usually starting from the first element of the list, until
either the target is found, or the end of the list is reached. This method is called linear search.

The average no. of elements to be examined before finding the target is N / 2 when the list has N
elements.

e.g. To find the data with User ID = 1491639, one must make 6 comparisons when the first 6 items
are checked to find the required data at alst[5] with the following linear search code:

## Linear Search ##
targetID = 1491639
targetIdx = None # a way to tell if it is not found
for i in range(len(alst)):
if alst[i][0] == targetID:
targetIdx = i
break

if targetIdx != None:
print("ID:", targetID)
print("Age:", alst[targetIdx][1])
print("Height:", alst[targetIdx][2])
else:
print("Not found")
(Note: A search operation might fail. When the target is not inside the list, the target position can be
set to None as a way to indicate this situation)

If the size of the list is large (e.g. with millions of elements), then the comparisons to make would be
huge on average and the linear search method would be highly inefficient.

Binary search
If the set of data is sorted, there is a faster way to find the target.

Consider the following sorted list of integers:

a = [12, 16, 19, 23, 35, 41, 45]

Suppose we want to find the position of the data 41 in the list.

The basic idea is to keep track of the range of index of the elements to search in each iteration, and
narrow down the range if the middle element of the range does not match the target.

At first, we know that the target should be somewhere between a[0] and a[6] (inclusive)

In the first round: Let start = 0, end = 6

Then, we examine the element in the middle of the range;

mid = (start + end) // 2 (use the integer results of the division)


= (0 + 6) // 2 = 3

So we examine a[3] and compare it with the target 41

Now, 41 > a[3] (=23), so we know that the target must be on the right (a[4] to a[6])
The range to search is reduced by half in the next round.

In the next round: Let start = 4, end = 6

The above steps of calculating mid and comparing a[mid] with target is repeated:

mid = (start + end) // 2 = (4 + 6) // 2 = 5

Compare a[5] with 41. It is the same!. So the target index is 5.


Only 2 comparisons are made to find the target.
What happens if we try to find target = 18 ? (not exist in the list)

Let's start again, with start = 0, end = 6.

=> mid = (0+6) // 2 = 3. Compare a[3] (=23) with 18.

As 18 < a[3], the target is on the left. Use end = mid-1 , same start in the next round.

Let start = 0, end = 3-1 = 2

=> mid = (0+2) // 2 = 1. Compare a[1] (= 16) with 18.

As 18 > a[1], the target is on the right. Use start = mid+1 , same end in the next round.

Let start = 1+1 = 2, end = 2.

=> mid = (2+2) // 2 = 2. Compare a[2] (= 19) with 18.

As 18 < a[2], the target is on the left. Use end = mid-1, same start in the next round.
But this is not a valid range! We should always have start <= end.

Whenever you have start > end, it indicates that the target is not inside the list.

The steps of binary search are summarized below:

1. Let start = 0 and end = len(a) - 1


2. The range of elements to search is a[start] to a[end] (inclusive)
Check if start > end, set idx to None to indicate target not found and end the search
3. Calculate the index of the element in the middle of the range:
mid = (start + end) // 2 # note that we want integer results only
4. If a[ mid ] is the target, then set idx to mid and end the search
5. If a[ mid ] < target, repeat from step 2 with start = mid + 1, end as before
6. If target < a[ mid ], repeat from step 2 with start as before, end = mid - 1

After these steps, we have either idx == None or a[ idx ] == target.

In Python, we can implement the search as a recursive function, with the last two steps (5 and 6) as
recursive function calls.

def bsearch( alst, start, end, target ):


if start > end: # invalid range => not found
return None
mid = (start + end) // 2
if alst[mid] == target:
return mid
if alst[mid] < target:
return bsearch( alst, mid+1, end, target )
else:
return bsearch( alst, start, mid-1, target )

The function is used as shown:

idx = bsearch( a, 0, len(a)-1, 41 )


if idx != None:
print( "41 at a[", idx, "]" )
else:
print( "41 not found in a" )
idx = bsearch( a, 0, len(a)-1, 18 )
if idx != None:
print( "18 at a[", idx, "]" )
else:
print( "18 not found in a" )

To make it slightly more convenient to use, we can write another function to call bsearch with the initial
start and end values:

def binarySearch( alst, target ):


return bsearch( alst, 0, len( alst ) - 1, target )

Exercise

In this exercise, we will reuse the files in the last assignment modify the content as follows:

T2_Ex4_class_class no_mod.py :

1. Copy your last assignment module file T2_Ex3_class_class no_mod.py and save it as
T2_Ex4_class_class no_mod.py (with your actual class and class no in the filename)

2. Add a bsearchID function to the module file that searches for a tuple in the list of tuples where
the first component of the tuple (User ID) matches the targetID.

def bsearchID( tplst, start, end, targetID ):


... ...

Hint: just need to make the following changes to the bsearch example:
alst to tplst
alst[mid] to tplst[mid][0]
target to targetID
bsearch to bsearchID (in the recursive calls)

3. Add a binarySearchID function to the module file to make it easier to use

def binarySearchID( tplst, targetID ):


return bsearchID( tplst, 0, len( tplst ) - 1, targetID )

T2_Ex4_class_class no_usemod.py :

4. Copy your last assignment module file T2_Ex3_class_class no_usemod.py and save it as
T2_Ex4_class_class no_usemod.py (with your actual class and class no in the filename)
5. Modify the module import line to import the Ex4 mod file:

import T2_Ex4_class_class_no_mod as mylib

6. Remove the code that shows the upper-quartile of each sorting result. You just need to sort
the list of tuples according to the User ID.

7. Add code to ask the user for an input of user ID to search (remember to convert the input into
integer). Call the binarySearchID function in the module file to search and print the results.
Repeat this process until the user has entered 0 for the user ID to search.

Sample output of T2_Ex4_class_class no_usemod.py : (user inputs are underlined)

Enter User ID to search: 1452336


Record found.
User ID: 1452336
Age: 58
Height: 164

Enter User ID to search: 1452339


Record not found

Enter User ID to search: 0


Bye

8. Submit a zip file of the two .py files using the name T2_Ex4_class_class no.zip with your
actual class and class no in the filename.

You might also like