import random
import time
import sys


def printf(format, *args):
    sys.stdout.write(format % args)

aPGElist = []
listLen = 1000  # length of searched list

# --------------------------------------------------
# a list is printed only if it contains less than printlim values
printlim = 12
printlim = 20

# --------------------------------------------------
# Function creates a list filled with randomly chosen values

def generate( listSize, maxval  ):
    random.seed(12321)
    t1 = time.time()
    aList = [random.randint(0, maxval) for x in range(listLen)]
    t2 = time.time()
    #printf("time generating %f\n", t2-t1  )
    if listLen < printlim: print(aList)
    return aList

# --------------------------------------------------
# manipulate the problem size n and maximum list value to see varying results
listSize = 10000
maxval = 10000

# listSize = 10
#maxval = 10
print( "List length =", listSize, ", maximum value =", maxval )

# how many different values are there in the list?

# For demonstration purposes, the list is searched for
# each value. The total number of the search hits is counted.
# That also gives the number of different values in the list.

# ----------------------------------------------------------------
#   SEARCH UNSORTED LIST
# ----------------------------------------------------------------

# search in an unsorted list -- by *index* method
print("search in an UNsorted list -- *index* ")
aPGElist = generate(listSize, maxval)
t1 = time.time()
count = 0
for value in range(maxval+1):
    try:
        indx = aPGElist.index(value)
        count += 1
    except ValueError:
        pass
t2 = time.time()
printf("Num of different values %d\n", count)
printf("        time %f\n\n", t2-t1 )


# search in an unsorted list -- *in*
print(" search in an UNsorted list -- *in* ")
aPGElist = generate(listSize, maxval)
t1 = time.time()
count = 0
for value in range(maxval+1):
    if value in aPGElist:
        count += 1
t2 = time.time()
printf("Num of different values %d\n", count)
printf("        time %f\n\n", t2-t1 )

# ----------------------------------------------------------------
#    SEARCH  SORTED  LIST
# ----------------------------------------------------------------

# search in a sorted list -- *index*
print(" search in a sorted list -- *index* ")
aPGElist = generate(listSize, maxval)
aPGElist.sort()
t1 = time.time()
count = 0
for value in range(maxval+1):
    try:
        indx = aPGElist.index(value)
        count += 1
    except ValueError:
        pass
t2 = time.time()
printf("Num of different values %d\n", count)
printf("        time %f\n\n", t2-t1 )


# search in an unordered list -- *in*
print(" search in an ordered list -- *in* ")
taPGElist = generate(listSize, maxval)
aPGElist.sort()
p1 = time.time()
count = 0
for value in range(maxval+1):
    if value in aPGElist:
        count += 1
t2 = time.time()
printf("Num of different values %d\n", count)
printf("        time %f\n\n", t2-t1 )

# ----------------------------------------------------------------
#    SEARCH SORTED LIST WITH     BINARY SEARCH
# ----------------------------------------------------------------

#  --------------------------------------------------
# Binary search function
# It is widely used for its efficiency.
def binarySearch( arr, value ):
    low = 0; high = len(arr)-1
    while low < high:    # while segment length > 1
        mid = (low + high) // 2
        if arr[mid] < value: low  = mid+1
        else:                 high = mid
    if arr[low] == value: return low  # found or
    return -1 # not found


# search in an ordered list -- *binary search*

print(" search in an ordered list -- *binary search* ")
aPGElist = generate(listSize, maxval)
aPGElist.sort()
t1 = time.time()
count = 0
for value in range(maxval+1):
    if binarySearch(aPGElist, value) != -1:  # if found
        count += 1
t2 = time.time()
printf("Num of different values %d\n", count)
printf("        time %f\n\n", t2-t1 )








