├── Abstract Data Types ├── Deque │ ├── Implementation.py │ └── Palindrome_Checker.py ├── Graph │ ├── Edges.txt │ └── Implementation.py ├── Lists │ ├── Ordered Lists │ │ └── Implementation.py │ └── Unordered Lists │ │ └── Implementation.py ├── Queue │ ├── Hot_Potato_game.py │ ├── Implementation.py │ └── Printer_Simulation.py └── Stack │ ├── Anything_to_Binary.py │ ├── Comp_Paranthesis_Checker.py │ ├── Decimal_to_Binary.py │ ├── Implementation.py │ ├── Infix_to_postfix.py │ ├── Paranthesis_Checker.py │ ├── Postfix_optimization.py │ └── Reverse_String.py ├── Data Structure Performance Analysis └── Lists.py ├── Dynamic Programming ├── fibo_dp.py └── max_subarray.py ├── Exception_Handling.py ├── Graph Theory ├── Basics.py ├── bfs.py ├── degree.py └── paths.py ├── Hashing ├── Imlementation.py ├── String_Hashing_ana_check.py └── String_Hashng.py ├── Machine Learning └── neuralnetwork.py ├── OOP Concepts ├── Logic_Gates.py └── OOP_Class.py ├── OOP_Class.py ├── README.md ├── Recursion ├── Int_to_str_rec.py ├── Palin_rec.py ├── Reverse_String_rec.py ├── Sum_of_list_rec.py ├── Turtle_Vis │ └── Spiral_rec.py └── fibo.py ├── Searching ├── Binary_Search.py ├── Binary_Search_OL.py ├── Sequential_Search.py └── Sequential_Search_OL.py └── Trees └── bin_tree.py /Abstract Data Types/Deque/Implementation.py: -------------------------------------------------------------------------------- 1 | class Deque: 2 | 3 | def __init__(self): 4 | self.items = [] 5 | 6 | def isEmpty(self): 7 | return self.items == [] 8 | 9 | def addFront(self, item): 10 | return self.items.append(item) 11 | 12 | def addRear(self,item): 13 | return self.items.insert(0,item) 14 | 15 | def removeFront(self): 16 | return self.items.pop() 17 | 18 | def removeRear(self): 19 | return self.items.pop(0) 20 | 21 | def size(self): 22 | return len(self.items) 23 | 24 | 25 | 26 | # p = Deque() 27 | # p.addFront(2) 28 | # p.addRear(True) 29 | 30 | # print(p.removeFront()) 31 | # print(p.removeFront()) 32 | -------------------------------------------------------------------------------- /Abstract Data Types/Deque/Palindrome_Checker.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def checker(palin): 4 | outdeq = Deque() 5 | 6 | for i in palin: 7 | outdeq.addRear(i) 8 | 9 | Equal = True 10 | 11 | while (outdeq.size() > 1) and Equal: 12 | first = outdeq.removeFront() 13 | last = outdeq.removeRear() 14 | 15 | if first.lower() != last.lower(): 16 | Equal = False 17 | else: 18 | Equal 19 | 20 | return Equal 21 | 22 | 23 | #print checker("Noon") 24 | -------------------------------------------------------------------------------- /Abstract Data Types/Graph/Edges.txt: -------------------------------------------------------------------------------- 1 | 1,2 2 | 1,4 3 | 3,2 4 | 2,5 5 | 4,1 6 | 3,5 -------------------------------------------------------------------------------- /Abstract Data Types/Graph/Implementation.py: -------------------------------------------------------------------------------- 1 | 2 | #The vertex data structure 3 | class Vertex: 4 | def __init__(self,key): 5 | self.id = key 6 | self.connectedTo = {} 7 | 8 | def addNeighbor(self,nbr,weight=0): 9 | self.connectedTo[nbr] = weight 10 | 11 | def __str__(self): 12 | return str(self.id) + ' connectedTo: ' + str([x.id for x in self.connectedTo]) 13 | 14 | def getConnections(self): 15 | return self.connectedTo.keys() 16 | 17 | def getId(self): 18 | return self.id 19 | 20 | def getWeight(self,nbr): 21 | return self.connectedTo[nbr] 22 | 23 | 24 | #The overall Graph data structure 25 | 26 | class Graph: 27 | def __init__(self): 28 | self.vertList = {} 29 | self.numVertices = 0 30 | 31 | def addVertex(self,key): 32 | self.numVertices = self.numVertices + 1 33 | newVertex = Vertex(key) 34 | self.vertList[key] = newVertex 35 | return newVertex 36 | 37 | def getVertex(self,n): 38 | if n in self.vertList: 39 | return self.vertList[n] 40 | else: 41 | return None 42 | 43 | def __contains__(self,n): 44 | return n in self.vertList 45 | 46 | def addEdge(self,f,t,cost=0): 47 | if f not in self.vertList: 48 | nv = self.addVertex(f) 49 | if t not in self.vertList: 50 | nv = self.addVertex(t) 51 | self.vertList[f].addNeighbor(self.vertList[t], cost) 52 | 53 | def getVertices(self): 54 | return self.vertList.keys() 55 | 56 | def __iter__(self): 57 | return iter(self.vertList.values()) 58 | 59 | 60 | f = open("C:\\Users\\acer\\Desktop\\Pythonic-Algorithm-Implementations\\Abstract Data Types\\Graph\\Edges.txt") 61 | 62 | g = Graph() 63 | buff = [] 64 | buff1 = [] 65 | buff2 = [] 66 | #links = [[] for i in xrange(len(set(buff)))] 67 | for line in f: 68 | buff1.append(line[0]) 69 | buff2.append(line[2]) 70 | buff.append(line[0]) 71 | buff.append(line[2]) 72 | 73 | g.addEdge(line[0],line[2]) 74 | g.addEdge(line[2],line[0]) 75 | 76 | for v in g: 77 | print v 78 | 79 | #for i in range(len(buff)): 80 | # g.addVertex(buff[i]) 81 | 82 | #for j in range(len(buff1)): 83 | # for k in range(len(buff2)): 84 | # g.addEdge(buff1[j],buff2[k]) 85 | 86 | print g.getVertices() 87 | print g.getVertex(2) 88 | 89 | 90 | 91 | 92 | f.close() 93 | 94 | #print buff 95 | #print set(buff) 96 | 97 | -------------------------------------------------------------------------------- /Abstract Data Types/Lists/Ordered Lists/Implementation.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | #For creating a single node 4 | 5 | class Node: 6 | def __init__(self,initdata): 7 | self.data = initdata 8 | self.next = None 9 | 10 | def getData(self): 11 | return self.data 12 | 13 | def getNext(self): 14 | return self.next 15 | 16 | def setData(self,newdata): 17 | self.data = newdata 18 | 19 | def setNext(self,newnext): 20 | self.next = newnext 21 | 22 | 23 | #Now, we create the ordered list class 24 | 25 | class OrderedList: 26 | 27 | def __init__(self): 28 | self.head = None 29 | 30 | def search(self, item): 31 | current = self.head 32 | found = False 33 | stop = False 34 | while current != None and not found and not stop: 35 | if current.getData() == item: 36 | found = True 37 | else: 38 | if current.getData() > item: 39 | stop = True 40 | else: 41 | current = current.getNext() 42 | 43 | return found 44 | 45 | #Traverses theough the list and adds in the item. 46 | def add(self, item): 47 | current = self.head 48 | previous = None 49 | stop = False 50 | #The traversal going on. Previous is used, because we want to follow one position behind the current node 51 | #in order to add. Ex: 31, 45, 56. We want to add 36. So, we traverse through the list and reach till 45. 52 | #So, now we want to add the current number behind 45. 53 | while current != None and not stop: 54 | if current.getData() > item: 55 | stop = True 56 | else: 57 | previous = current 58 | current = current.getNext() 59 | #If there is no previous, it means that the node is the head. Else, we need to insert the number and assign 60 | #previous and next accordingly to the neighbouring elements. 61 | temp = Node(item) 62 | if previous == None: 63 | temp.setNext(self.head) 64 | self.head = temp 65 | else: 66 | temp.setNext(current) 67 | previous.setNext(temp) 68 | 69 | def isEmpty(self): 70 | return self.head == True 71 | 72 | def size(self): 73 | current = self.head 74 | count = 0 75 | while current != None: 76 | count += 1 77 | current = current.getNext() 78 | return count 79 | 80 | 81 | 82 | #Examples for testing. Please uncomment, for usage. 83 | # mylist = OrderedList() 84 | # mylist.add(31) 85 | # mylist.add(77) 86 | # mylist.add(17) 87 | # mylist.add(93) 88 | # mylist.add(26) 89 | # mylist.add(54) 90 | 91 | # print(mylist.size()) 92 | # print(mylist.search(93)) 93 | # print(mylist.search(100)) 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Abstract Data Types/Lists/Unordered Lists/Implementation.py: -------------------------------------------------------------------------------- 1 | ''' An unordered list is a list in which the elements are linked to each other. 2 | And why is it called "unordered" ? 3 | You'll know it when you get to the Ordered List explanation. 4 | ''' 5 | 6 | #For creating a single node 7 | 8 | class Node: 9 | def __init__(self,initdata): 10 | self.data = initdata 11 | self.next = None 12 | 13 | def getData(self): 14 | return self.data 15 | 16 | def getNext(self): 17 | return self.next 18 | 19 | def setData(self,newdata): 20 | self.data = newdata 21 | 22 | def setNext(self,newnext): 23 | self.next = newnext 24 | 25 | 26 | #For creating a Linked List 27 | 28 | class UnorderedList: 29 | 30 | def __init__(self): 31 | self.head = None 32 | 33 | def isEmpty(self): 34 | return self.head == None 35 | 36 | #We always add the new item as the head of the list(most convenient). 37 | def add(self,item): 38 | temp = Node(item) 39 | temp.setNext(self.head) 40 | self.head = temp 41 | 42 | #This method is famously called the Linked List traversal. 43 | def size(self): 44 | current = self.head 45 | count = 0 46 | while current != None: 47 | count = count + 1 48 | current = current.getNext() 49 | 50 | return count 51 | 52 | #Another linked-list traversal example. 53 | def search(self,item): 54 | current = self.head 55 | found = False 56 | while current != None and not found: 57 | if current.getData() == item: 58 | found = True 59 | else: 60 | current = current.getNext() 61 | 62 | return found 63 | 64 | 65 | #Observe how the list is being sewn up, after removing a node. 66 | def remove(self,item): 67 | current = self.head 68 | previous = None 69 | found = False 70 | while not found: 71 | if current.getData() == item: 72 | found = True 73 | else: 74 | previous = current 75 | current = current.getNext() 76 | 77 | if previous == None: 78 | self.head = current.getNext() 79 | else: 80 | previous.setNext(current.getNext()) 81 | 82 | def append(self, item): 83 | found = False 84 | while not found: 85 | if current.getNext() == None: 86 | current.setNext(item) 87 | found = True 88 | else: 89 | current = current.getNext 90 | 91 | def index_of(self, data): 92 | """Find the position of a node in the list""" 93 | current = self.head 94 | pos = 0 95 | 96 | while current != None: 97 | if (current.data == data): 98 | return pos 99 | else: 100 | current = current.getNext 101 | pos = pos + 1 102 | 103 | return pos 104 | 105 | 106 | # Should also create methods for insert and pop(easy) 107 | 108 | 109 | # mylist = UnorderedList() 110 | 111 | # mylist.add(31) 112 | # mylist.add(77) 113 | # mylist.add(17) 114 | # mylist.add(93) 115 | # mylist.add(26) 116 | # mylist.add(54) 117 | 118 | # print(mylist.size()) 119 | # print(mylist.search(93)) 120 | # print(mylist.search(100)) 121 | 122 | # mylist.add(100) 123 | # print(mylist.search(100)) 124 | # print(mylist.size()) 125 | 126 | # mylist.remove(54) 127 | # print(mylist.size()) 128 | # mylist.remove(93) 129 | # print(mylist.size()) 130 | # mylist.remove(31) 131 | # print(mylist.size()) 132 | # print(mylist.search(93)) 133 | -------------------------------------------------------------------------------- /Abstract Data Types/Queue/Hot_Potato_game.py: -------------------------------------------------------------------------------- 1 | 2 | def Hot_Pop(names, num): 3 | stack_imp = Queue() 4 | 5 | for i in names: 6 | stack_imp.enqueue(i) 7 | 8 | while stack_imp.size() > 1: 9 | for j in range(num): 10 | stack_imp.enqueue(stack_imp.dequeue()) 11 | 12 | stack_imp.dequeue() 13 | 14 | return stack_imp.dequeue() 15 | 16 | 17 | #print(Hot_Pop(["Bill","David","Susan","Jane","Kent","Brad"],7)) 18 | 19 | -------------------------------------------------------------------------------- /Abstract Data Types/Queue/Implementation.py: -------------------------------------------------------------------------------- 1 | class Queue: 2 | 3 | def __init__(self): 4 | self.items = [] 5 | 6 | def isEmpty(self): 7 | return self.items == [] 8 | 9 | def enqueue(self,item): 10 | self.items.insert(0,item) 11 | 12 | def dequeue(self): 13 | return self.items.pop() 14 | 15 | def size(self): 16 | return len(self.items) 17 | 18 | 19 | # q = Queue() 20 | # #print(q.isEmpty()) 21 | # q.enqueue(2) 22 | # print(q.isEmpty()) 23 | 24 | # q.dequeue() 25 | # print(q.isEmpty()) -------------------------------------------------------------------------------- /Abstract Data Types/Queue/Printer_Simulation.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | class Queue: 4 | 5 | def __init__(self): 6 | self.items = [] 7 | 8 | def isEmpty(self): 9 | return self.items == [] 10 | 11 | def enqueue(self,item): 12 | self.items.insert(0,item) 13 | 14 | def dequeue(self): 15 | return self.items.pop() 16 | 17 | def size(self): 18 | return len(self.items) 19 | 20 | 21 | class Printer: 22 | def __init__(self, ppm): 23 | self.pagerate = ppm 24 | self.currentTask = None 25 | self.timeRemaining = 0 26 | 27 | def tick(self): 28 | if self.currentTask != None: 29 | self.timeRemaining = self.timeRemaining - 1 30 | if self.timeRemaining <= 0: 31 | self.currentTask = None 32 | 33 | def busy(self): 34 | if self.currentTask != None: 35 | return True 36 | else: 37 | return False 38 | 39 | def startNext(self,newtask): 40 | self.currentTask = newtask 41 | self.timeRemaining = newtask.getPages() * 60/self.pagerate 42 | 43 | class Task: 44 | def __init__(self,time): 45 | self.timestamp = time 46 | self.pages = random.randrange(1,21) 47 | 48 | def getStamp(self): 49 | return self.timestamp 50 | 51 | def getPages(self): 52 | return self.pages 53 | 54 | def waitTime(self, currenttime): 55 | return currenttime - self.timestamp 56 | 57 | 58 | def simulation(numSeconds, pagesPerMinute): 59 | 60 | labprinter = Printer(pagesPerMinute) 61 | printQueue = Queue() 62 | waitingtimes = [] 63 | 64 | for currentSecond in range(numSeconds): 65 | 66 | if newPrintTask(): 67 | task = Task(currentSecond) 68 | printQueue.enqueue(task) 69 | 70 | if (not labprinter.busy()) and (not printQueue.isEmpty()): 71 | nexttask = printQueue.dequeue() 72 | waitingtimes.append( nexttask.waitTime(currentSecond)) 73 | labprinter.startNext(nexttask) 74 | 75 | labprinter.tick() 76 | 77 | averageWait=sum(waitingtimes)/len(waitingtimes) 78 | print("Average Wait %6.2f secs %3d tasks remaining."%(averageWait,printQueue.size())) 79 | 80 | def newPrintTask(): 81 | num = random.randrange(1,181) 82 | if num == 180: 83 | return True 84 | else: 85 | return False 86 | 87 | for i in range(10): 88 | simulation(3600,5) 89 | -------------------------------------------------------------------------------- /Abstract Data Types/Stack/Anything_to_Binary.py: -------------------------------------------------------------------------------- 1 | 2 | def any_to_bin(number,base): 3 | digits = "0123456789ABCDEF" 4 | rem = Stack() 5 | 6 | while number > 0: 7 | reminder = number % base 8 | rem.push(reminder) 9 | number = number // base 10 | 11 | binary = "" 12 | while not rem.isEmpty(): 13 | binary = binary + digits[rem.pop()] 14 | 15 | return binary 16 | 17 | 18 | print(any_to_bin(42,8)) -------------------------------------------------------------------------------- /Abstract Data Types/Stack/Comp_Paranthesis_Checker.py: -------------------------------------------------------------------------------- 1 | 2 | #Please import the stack module before running this example. 3 | 4 | def CompParenCheck(symbolString): 5 | s = Stack() 6 | balanced = True 7 | index = 0 8 | while index < len(symbolString) and balanced: 9 | symbol = symbolString[index] 10 | if symbol in "([{": 11 | s.push(symbol) 12 | else: 13 | if s.isEmpty(): 14 | balanced = False 15 | else: 16 | top = s.pop() 17 | if not matches(top,symbol): 18 | balanced = False 19 | index = index + 1 20 | if balanced and s.isEmpty(): 21 | return True 22 | else: 23 | return False 24 | 25 | def matches(open,close): 26 | opens = "([{" 27 | closers = ")]}" 28 | return opens.index(open) == closers.index(close) 29 | 30 | 31 | #print CompParenCheck("{({)}") -------------------------------------------------------------------------------- /Abstract Data Types/Stack/Decimal_to_Binary.py: -------------------------------------------------------------------------------- 1 | 2 | def dec_to_bin(number): 3 | rem = Stack() 4 | 5 | while number > 0: 6 | reminder = number % 2 7 | rem.push(reminder) 8 | number = number // 2 9 | 10 | binary = "" 11 | while not rem.isEmpty(): 12 | binary = binary + str(rem.pop()) 13 | 14 | return binary 15 | 16 | 17 | #print(dec_to_bin(24)) -------------------------------------------------------------------------------- /Abstract Data Types/Stack/Implementation.py: -------------------------------------------------------------------------------- 1 | class Stack: 2 | 3 | def __init__(self): 4 | self.items = [] 5 | 6 | def isEmpty(self): 7 | return self.size() == 0 8 | 9 | def push(self,item): 10 | return self.items.insert(0,item) 11 | 12 | def pop(self): 13 | return self.items.pop(0) 14 | 15 | def peek(self): 16 | return self.items[0] 17 | 18 | def size(self): 19 | return len(self.items) 20 | 21 | 22 | 23 | 24 | #Now, creating a Stack object 25 | 26 | # s = Stack() 27 | # s.push(4) 28 | # s.push("Dog") 29 | # s.push(True) 30 | 31 | # #print(s.size()) 32 | # #print(s.peek()) 33 | # #print(s.isEmpty()) 34 | 35 | # s.push(8.4) 36 | 37 | # #print(s.pop()) 38 | # #print(s.pop()) 39 | # #print(s.pop()) 40 | # #print(s.pop()) 41 | -------------------------------------------------------------------------------- /Abstract Data Types/Stack/Infix_to_postfix.py: -------------------------------------------------------------------------------- 1 | #Please import the Stackmodule before running this program. 2 | 3 | def infixToPostfix(infixexpr): 4 | prec = {} 5 | prec["*"] = 3 6 | prec["/"] = 3 7 | prec["+"] = 2 8 | prec["-"] = 2 9 | prec["("] = 1 10 | opStack = Stack() 11 | postfixList = [] 12 | tokenList = infixexpr.split() 13 | 14 | for token in tokenList: 15 | if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token in "0123456789": 16 | postfixList.append(token) 17 | elif token == '(': 18 | opStack.push(token) 19 | elif token == ')': 20 | topToken = opStack.pop() 21 | while topToken != '(': 22 | postfixList.append(topToken) 23 | topToken = opStack.pop() 24 | else: 25 | while (not opStack.isEmpty()) and \ 26 | (prec[opStack.peek()] >= prec[token]): 27 | postfixList.append(opStack.pop()) 28 | opStack.push(token) 29 | 30 | while not opStack.isEmpty(): 31 | postfixList.append(opStack.pop()) 32 | return " ".join(postfixList) 33 | 34 | #print(infixToPostfix("A * B + C * D")) 35 | #print(infixToPostfix("( A + B ) * C - ( D - E ) * ( F + G )")) 36 | -------------------------------------------------------------------------------- /Abstract Data Types/Stack/Paranthesis_Checker.py: -------------------------------------------------------------------------------- 1 | #Please import the Stack class from the Implementation file. 2 | 3 | def parChecker(symbolString): 4 | s = Stack() 5 | balanced = True 6 | index = 0 7 | while index < len(symbolString) and balanced: 8 | symbol = symbolString[index] 9 | if symbol == "(": 10 | s.push(symbol) 11 | else: 12 | if s.isEmpty(): 13 | balanced = False 14 | else: 15 | s.pop() 16 | 17 | index = index + 1 18 | 19 | if balanced and s.isEmpty(): 20 | return True 21 | else: 22 | return False 23 | 24 | #print(parChecker('((()))')) 25 | #print(parChecker('(()')) 26 | -------------------------------------------------------------------------------- /Abstract Data Types/Stack/Postfix_optimization.py: -------------------------------------------------------------------------------- 1 | 2 | def postfix_opt(target): 3 | operandstack = Stack() 4 | tokenList = target.split() 5 | 6 | for token in tokenList: 7 | if token in "1234567890" : 8 | operandstack.push(int(token)) 9 | else: 10 | second = operandstack.pop() 11 | first = operandstack.pop() 12 | result = doMath(token,first,second) 13 | operandstack.push(result) 14 | return operandstack.pop() 15 | 16 | def doMath(op, op1, op2): 17 | if op == "+": 18 | return op1 + op2 19 | elif op == "*": 20 | return op1 * op2 21 | elif op == "/": 22 | return op1 / op2 23 | elif op == "-": 24 | return op1 - op2 25 | else: 26 | return op1 ^ op2 27 | 28 | 29 | 30 | print(postfix_opt('7 8 + 3 2 + /')) 31 | -------------------------------------------------------------------------------- /Abstract Data Types/Stack/Reverse_String.py: -------------------------------------------------------------------------------- 1 | class Stack: 2 | 3 | def __init__(self): 4 | self.items = [] 5 | 6 | def isEmpty(self): 7 | return self.size() == 0 8 | 9 | def push(self,item): 10 | return self.items.insert(0,item) 11 | 12 | def pop(self): 13 | return self.items.pop(0) 14 | 15 | def peek(self): 16 | return self.items[0] 17 | 18 | def size(self): 19 | return len(self.items) 20 | 21 | #I tend to write the Stack implementation class in every example, just to \ 22 | # practise writing code. However it can simply be imported as a module too. 23 | 24 | def Str_rev(target): 25 | 26 | stack_obj = Stack() 27 | for char in target: 28 | stack_obj.push(char) 29 | 30 | while not stack_obj.isEmpty(): 31 | print(stack_obj.pop()) 32 | 33 | #An alternative implementation would be: 34 | for i in range(stack_obj.size()): 35 | print stack_obj.pop() 36 | 37 | 38 | print(Str_rev("ABC")) -------------------------------------------------------------------------------- /Data Structure Performance Analysis/Lists.py: -------------------------------------------------------------------------------- 1 | from timeit import default_timer 2 | 3 | def list1(): 4 | start = default_timer() 5 | l = [] 6 | for i in range(1000): 7 | l = l + [i] 8 | duration = default_timer() - start 9 | return duration 10 | 11 | def list2(): 12 | start = default_timer() 13 | l = [] 14 | for i in range(1000): 15 | l.append(i) 16 | duration = default_timer() - start 17 | return duration 18 | 19 | def list3(): 20 | start = default_timer() 21 | l = [i for i in range(1000)] 22 | duration = default_timer() - start 23 | return duration 24 | 25 | def list4(): 26 | start = default_timer() 27 | l = list(range(1000)) 28 | duration = default_timer() - start 29 | return duration 30 | 31 | 32 | print list1() 33 | print list2() 34 | print list3() 35 | print list4() 36 | 37 | '''Running Time Analysis: 38 | list1 > list2 > list3 > list4 39 | ''' 40 | #Popping from an end of the list takes O(1); while anywhere in the middle, it in O(n), as the list needs to re-size -------------------------------------------------------------------------------- /Dynamic Programming/fibo_dp.py: -------------------------------------------------------------------------------- 1 | def fibo_dp(n): 2 | n2, n1 = 0, 1 3 | 4 | for i in range(0, n-2): 5 | n2, n1 = n1, n1+n2 6 | 7 | return n2 + n1 8 | 9 | print fibo_dp(5) 10 | -------------------------------------------------------------------------------- /Dynamic Programming/max_subarray.py: -------------------------------------------------------------------------------- 1 | #t is the sum of the sub-array; s in the optimal array sum 2 | 3 | def max_subarray(a): 4 | 5 | s = -float('infinity') 6 | t = 0 7 | 8 | for i in range(len(a)): 9 | t = t + a[i] 10 | 11 | if t > s: 12 | s = t 13 | 14 | elif t < 0: 15 | t = 0 16 | 17 | return(s) 18 | 19 | 20 | print max_subarray([1,2,-5,4,7,-2]) 21 | -------------------------------------------------------------------------------- /Exception_Handling.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | num = int(input("Pl enter")) 4 | 5 | 6 | try: 7 | print(math.sqrt(num)) 8 | except: 9 | print("Bad value") 10 | print("Using absolute value") 11 | print(int(abs(num))) 12 | 13 | ##if num<0: 14 | ## raise RuntimeError("No negatives") 15 | ##else: 16 | ## print(math.sqrt(num)) -------------------------------------------------------------------------------- /Graph Theory/Basics.py: -------------------------------------------------------------------------------- 1 | graph = { "a" : ["c"], 2 | "b" : ["c", "e"], 3 | "c" : ["a", "b", "d", "e"], 4 | "d" : ["c"], 5 | "e" : ["c", "b"], 6 | "f" : [] 7 | } 8 | 9 | def generate_edges(graph): 10 | edges = [] 11 | 12 | for node in graph: 13 | for neighbour in graph[node]: 14 | edges.append((node,neighbour)) 15 | 16 | return edges 17 | 18 | print generate_edges(graph) 19 | 20 | def isolated_nodes(graph): 21 | isolated = [] 22 | for node in graph: 23 | if graph[node] == []: 24 | isolated += node 25 | return isolated 26 | 27 | print isolated_nodes(graph) 28 | -------------------------------------------------------------------------------- /Graph Theory/bfs.py: -------------------------------------------------------------------------------- 1 | graph = { "a" : set(["b","s"]), 2 | "b" : set(["a"]), 3 | "s" : set(["c","g"]), 4 | "c" : set(["d","f","e"]), 5 | "g" : set(["f"]), 6 | "d" : set(["c"]), 7 | "f" : set(["c","g"]), 8 | "e" : set(["c","h"]), 9 | "h" : set(["g","e"]) 10 | } 11 | 12 | 13 | 14 | def bfs(graph, start): 15 | visited, queue = set(), [start] 16 | while queue: 17 | vertex = queue.pop(0) 18 | if vertex not in visited: 19 | visited.add(vertex) 20 | #print visited 21 | queue.extend(graph[vertex] - visited) 22 | #print queue 23 | return visited 24 | 25 | 26 | print bfs(graph, 'a') 27 | -------------------------------------------------------------------------------- /Graph Theory/degree.py: -------------------------------------------------------------------------------- 1 | graph = {"a" : ["d"], 2 | "b" : ["c"], 3 | "c" : ["c","d","b","e"], 4 | "d" : ["a","c"], 5 | "e" : ["c"], 6 | "f" : [] 7 | } 8 | 9 | def degree(graph,vertex): 10 | deg = len(graph[vertex]) + graph[vertex].count(vertex) 11 | return deg 12 | 13 | print degree(graph,"f") 14 | -------------------------------------------------------------------------------- /Graph Theory/paths.py: -------------------------------------------------------------------------------- 1 | graph = { "a" : ["c"], 2 | "b" : ["c", "e"], 3 | "c" : ["a", "b", "d", "e"], 4 | "d" : ["c"], 5 | "e" : ["c", "b"], 6 | "f" : [] 7 | } 8 | 9 | def find_path(graph,start,end,path = []): 10 | path += start 11 | if start == end: 12 | return path 13 | 14 | if start not in graph: 15 | return None 16 | 17 | else: 18 | for vertex in graph[start]: 19 | if vertex not in path: 20 | ext_path = find_path(graph,vertex,end,path) 21 | 22 | if ext_path: 23 | return ext_path 24 | 25 | print find_path(graph,"a","e") 26 | 27 | def find_all_paths(graph,start,end,path = []): 28 | path += start 29 | if start == end: 30 | return path 31 | 32 | if start not in graph: 33 | return [] 34 | 35 | else: 36 | all_paths = [] 37 | for vertex in graph[start]: 38 | if vertex not in path: 39 | ext_path = find_all_paths(graph,vertex,end,path) 40 | 41 | for p in ext_path: 42 | all_paths.append(p) 43 | return all_paths 44 | 45 | print find_all_paths(graph,"d","e") 46 | 47 | -------------------------------------------------------------------------------- /Hashing/Imlementation.py: -------------------------------------------------------------------------------- 1 | #Hash Table implementation. 2 | 3 | class HashTable: 4 | 5 | #The constructor module. 6 | def __init__(self): 7 | self.size = 11 8 | self.slots = [None] * self.size 9 | self.data = [None] * self.size 10 | 11 | #The put(insert) module. 12 | def put(self,key,data): 13 | hashvalue = self.hashfun(key, len(self.slots)) 14 | 15 | if self.slots == None: 16 | self.slots[hashvalue] = key 17 | self.data[hashvalue] = data 18 | else: 19 | if self.slots == key: 20 | self.data[hashvalue] = data 21 | else: 22 | nextslot = self.rehash(hashvalue, len(self.slots)) 23 | while (self.slots[nextslot] != None) and (self.slots[nextslot] != key): 24 | nextslot = self.rehash(nextslot, len(self.slots)) 25 | 26 | if self.slots[nextslot] == None: 27 | self.slots[nextslot] = key 28 | self.data[nextslot] = data 29 | else: 30 | self.data[nextslot] = data 31 | 32 | #The hashfunc module 33 | def hashfun(self,key,size): 34 | return key%size 35 | 36 | #The re-hashfunc module for handling collisions. 37 | def rehash(slf, oldhash, size): 38 | return (oldhash+1)%size 39 | 40 | #The get(retrieve) module. 41 | def get(self,key): 42 | startslot = self.hashfunction(key,len(self.slots)) 43 | 44 | data = None 45 | stop = False 46 | found = False 47 | position = startslot 48 | while self.slots[position] != None and not found and not stop: 49 | if self.slots[position] == key: 50 | found = True 51 | data = self.data[position] 52 | else: 53 | position=self.rehash(position,len(self.slots)) 54 | if position == startslot: 55 | stop = True 56 | return data 57 | 58 | #The get item constructor module. 59 | def __getitem__(self,key): 60 | return self.get(key) 61 | 62 | #The set item constructor module 63 | def __setitem__(self,key,data): 64 | self.put(key,data) 65 | 66 | 67 | H = HashTable() 68 | H[54] = "cat" 69 | H[26] = "dog" 70 | H[93] = "lion" 71 | H[17] = "tiger" 72 | H[77] = "bird" 73 | H[31] = "cow" 74 | H[44] = "goat" 75 | H[55] = "pig" 76 | H[20] = "chicken" 77 | 78 | print H.slots 79 | print H.data 80 | -------------------------------------------------------------------------------- /Hashing/String_Hashing_ana_check.py: -------------------------------------------------------------------------------- 1 | #This algorithm ensures that nagrams are dealt differently during hashing. 2 | #This is done, by weighing the ordinal value by the char's position. 3 | #(i+1) because Python's indexing starts from 0. 4 | 5 | 6 | def str_ana_check(inp, table): 7 | sum = 0 8 | for i in range(len(inp)): 9 | sum += (ord(inp[i]))*(i+1) 10 | 11 | return sum%table 12 | 13 | print str_ana_check("cat", 11) 14 | -------------------------------------------------------------------------------- /Hashing/String_Hashng.py: -------------------------------------------------------------------------------- 1 | def hash_string(inp, table): 2 | sum = 0 3 | for i in range(len(inp)): 4 | sum += ord(inp[i]) 5 | return sum%table 6 | 7 | 8 | print hash_string("cat", 11) 9 | -------------------------------------------------------------------------------- /Machine Learning/neuralnetwork.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import dill 3 | 4 | class neural_network: 5 | 6 | def __init__(self, num_layers, num_nodes, activation_function, cost_function): 7 | self.num_layers = num_layers 8 | self.num_nodes = num_nodes 9 | self.layers = [] 10 | self.cost_function = cost_function 11 | 12 | for i in range(num_layers): 13 | if i != num_layers-1: 14 | layer_i = layer(num_nodes[i], num_nodes[i+1], activation_function[i]) 15 | else: 16 | layer_i = layer(num_nodes[i], 0, activation_function[i]) 17 | self.layers.append(layer_i) 18 | 19 | def train(self, batch_size, inputs, labels, num_epochs, learning_rate, filename): 20 | self.batch_size = batch_size 21 | self.learning_rate = learning_rate 22 | for j in range(num_epochs): 23 | i = 0 24 | print("== EPOCH: ", j, " ==") 25 | while i+batch_size != len(inputs): 26 | self.error = 0 27 | self.forward_pass(inputs[i:i+batch_size]) 28 | self.calculate_error(labels[i:i+batch_size]) 29 | self.back_pass(labels[i:i+batch_size]) 30 | i += batch_size 31 | print("Error: ", self.error) 32 | dill.dump_session(filename) 33 | 34 | def forward_pass(self, inputs): 35 | self.layers[0].activations = inputs 36 | for i in range(self.num_layers-1): 37 | self.layers[i].add_bias(self.batch_size, self.layers[i+1].num_nodes_in_layer) 38 | temp = np.add(np.matmul(self.layers[i].activations, self.layers[i].weights_for_layer), self.layers[i].bias_for_layer) 39 | if self.layers[i+1].activation_function == "sigmoid": 40 | self.layers[i+1].activations = self.sigmoid(temp) 41 | elif self.layers[i+1].activation_function == "softmax": 42 | self.layers[i+1].activations = self.softmax(temp) 43 | elif self.layers[i+1].activation_function == "relu": 44 | self.layers[i+1].activations = self.relu(temp) 45 | elif self.layers[i+1].activation_function == "tanh": 46 | self.layers[i+1].activations = self.tanh(temp) 47 | else: 48 | self.layers[i+1].activations = temp 49 | 50 | def relu(self, layer): 51 | layer[layer < 0] = 0 52 | return layer 53 | 54 | def softmax(self, layer): 55 | exp = np.exp(layer) 56 | return exp/np.sum(exp, axis=1, keepdims=True) 57 | 58 | def sigmoid(self, layer): 59 | return np.divide(1, np.add(1, np.exp(layer))) 60 | 61 | def tanh(self, layer): 62 | return np.tanh(layer) 63 | 64 | def calculate_error(self, labels): 65 | if len(labels[0]) != self.layers[self.num_layers-1].num_nodes_in_layer: 66 | print ("Error: Label is not of the same shape as output layer.") 67 | print("Label: ", len(labels), " : ", len(labels[0])) 68 | print("Out: ", len(self.layers[self.num_layers-1].activations), " : ", len(self.layers[self.num_layers-1].activations[0])) 69 | return 70 | 71 | if self.cost_function == "mean_squared": 72 | self.error = np.mean(np.divide(np.square(np.subtract(labels, self.layers[self.num_layers-1].activations)), 2)) 73 | elif self.cost_function == "cross_entropy": 74 | self.error = np.negative(np.sum(np.multiply(labels, np.log(self.layers[self.num_layers-1].activations)))) 75 | 76 | def back_pass(self, labels): 77 | # if self.cost_function == "cross_entropy" and self.layers[self.num_layers-1].activation_function == "softmax": 78 | targets = labels 79 | i = self.num_layers-1 80 | y = self.layers[i].activations 81 | deltaw = np.matmul(np.asarray(self.layers[i-1].activations).T, np.multiply(y, np.multiply(1-y, targets-y))) 82 | new_weights = self.layers[i-1].weights_for_layer - self.learning_rate * deltaw 83 | for i in range(i-1, 0, -1): 84 | y = self.layers[i].activations 85 | deltaw = np.matmul(np.asarray(self.layers[i-1].activations).T, np.multiply(y, np.multiply(1-y, np.sum(np.multiply(new_weights, self.layers[i].weights_for_layer),axis=1).T))) 86 | self.layers[i].weights_for_layer = new_weights 87 | new_weights = self.layers[i-1].weights_for_layer - self.learning_rate * deltaw 88 | self.layers[0].weights_for_layer = new_weights 89 | 90 | def predict(self, filename, input): 91 | dill.load_session(filename) 92 | self.batch_size = 1 93 | self.forward_pass(input) 94 | a = self.layers[self.num_layers-1].activations 95 | a[np.where(a==np.max(a))] = 1 96 | a[np.where(a!=np.max(a))] = 0 97 | return a 98 | 99 | def check_accuracy(self, filename, inputs, labels): 100 | dill.load_session(filename) 101 | self.batch_size = len(inputs) 102 | self.forward_pass(inputs) 103 | a = self.layers[self.num_layers-1].activations 104 | num_classes = 10 105 | targets = np.array([a]).reshape(-1) 106 | a = np.asarray(a) 107 | one_hot_labels = np.eye(num_classes)[a.astype(int)] 108 | total=0 109 | correct=0 110 | for i in range(len(a)): 111 | total += 1 112 | if np.equal(one_hot_labels[i], labels[i]).all(): 113 | correct += 1 114 | print("Accuracy: ", correct*100/total) 115 | 116 | 117 | 118 | def load_model(self, filename): 119 | dill.load_session(filename) 120 | 121 | 122 | class layer: 123 | def __init__(self, num_nodes_in_layer, num_nodes_in_next_layer, activation_function): 124 | self.num_nodes_in_layer = num_nodes_in_layer 125 | self.activation_function = activation_function 126 | self.activations = np.zeros([num_nodes_in_layer,1]) 127 | if num_nodes_in_next_layer != 0: 128 | self.weights_for_layer = np.random.normal(0, 0.001, size=(num_nodes_in_layer, num_nodes_in_next_layer)) 129 | else: 130 | self.weights_for_layer = None 131 | self.bias_for_layer = None 132 | 133 | def add_bias(self, batch_size, num_nodes_in_next_layer): 134 | if num_nodes_in_next_layer != 0: 135 | self.bias_for_layer = np.random.normal(0, 0.01, size=(batch_size, num_nodes_in_next_layer)) 136 | -------------------------------------------------------------------------------- /OOP Concepts/Logic_Gates.py: -------------------------------------------------------------------------------- 1 | class LogicGate: 2 | 3 | def __init__(self,n): 4 | self.label = n 5 | self.output = None 6 | 7 | def getLabel(self): 8 | return self.label 9 | 10 | def getOutput(self): 11 | self.output = self.performGateLogic() 12 | return self.output 13 | 14 | 15 | #As both the Binary and Unary gates are sub-classes of Logic Gate, we call the 16 | #Constructor instance of the super class. 17 | 18 | class BinaryGate(LogicGate): 19 | 20 | def __init__(self,n): 21 | LogicGate.__init__(self,n) 22 | 23 | self.pinA = None 24 | self.pinB = None 25 | 26 | def getPinA(self): 27 | return int(input("Enter Pin A " + self.getLabel() + ":")) 28 | 29 | def getPinB(self): 30 | return int(input("Enter Pin B " + self.getLabel() + ":")) 31 | 32 | 33 | class UnaryGate(LogicGate): 34 | 35 | def __init__(self,n): 36 | LogicGate.__init__(self,n) 37 | 38 | self.pin = None 39 | 40 | def getPin(self): 41 | if self.pin == None: 42 | return int(input("Enter Pin input for gate "+self.getLabel()+"-->")) 43 | else: 44 | return self.pin.getFrom().getOutput() 45 | 46 | def setNextPin(self,source): 47 | if self.pin == None: 48 | self.pin = source 49 | else: 50 | print("Cannot Connect: NO EMPTY PINS on this gate") 51 | 52 | 53 | class AndGate(BinaryGate): 54 | 55 | def __init__(self,n): 56 | BinaryGate.__init__(self,n) 57 | 58 | def performGateLogic(self): 59 | a = self.getPinA() 60 | b = self.getPinB() 61 | 62 | if a==1 and b==1: 63 | return 1 64 | else: 65 | return 0 66 | 67 | class ORGate(BinaryGate): 68 | 69 | def __init__(self,n): 70 | BinaryGate.__init__(self,n) 71 | 72 | def performGateLogic(self): 73 | a = self.getPinA() 74 | b = self.getPinB() 75 | 76 | if a==1 or b==1: 77 | return 1 78 | else: 79 | return 0 80 | 81 | class NOTGate(UnaryGate): 82 | 83 | def __init__(self,n): 84 | UnaryGate.__init__(self,n) 85 | 86 | def performGateLogic(self): 87 | a = self.getPin() 88 | 89 | if a == 1: 90 | return 0 91 | else: 92 | return 1 93 | 94 | 95 | class Connector: 96 | 97 | def __init__(self,fgate,tgate): 98 | self.fromgate = fgate 99 | self.togate = tgate 100 | 101 | tgate.setNextPin(self) 102 | 103 | def getFrom(self): 104 | return self.fromgate 105 | 106 | def getTo(self): 107 | return self.togate 108 | 109 | def setNextPin(self,source): 110 | if self.pinA == None: 111 | self.pinA = source 112 | else: 113 | if self.pinB == None: 114 | self.pinB = source 115 | else: 116 | raise RuntimeError("Error: No Empty Pins") 117 | 118 | 119 | 120 | # def main(): 121 | # g1 = AndGate("G1") 122 | # g2 = AndGate("G2") 123 | # g3 = OrGate("G3") 124 | # g4 = NotGate("G4") 125 | # c1 = Connector(g1,g3) 126 | # c2 = Connector(g2,g3) 127 | # c3 = Connector(g3,g4) 128 | # print(g4.getOutput()) 129 | 130 | 131 | # main() 132 | -------------------------------------------------------------------------------- /OOP Concepts/OOP_Class.py: -------------------------------------------------------------------------------- 1 | def gcd(m,n): 2 | while m%n != 0: 3 | oldm = m 4 | oldn = n 5 | 6 | m = oldn 7 | n = oldm%oldn 8 | return n 9 | 10 | class Fraction: 11 | def __init__(self,top,bottom): 12 | self.numer = top 13 | self.denom = bottom 14 | 15 | def __str__(self): 16 | return str(self.numer)+"/"+str(self.denom) 17 | 18 | def show(self): 19 | print(self.numer,"/",self.denom) 20 | 21 | def __add__(self,otherfraction): 22 | newnum = self.numer*otherfraction.denom + \ 23 | self.denom*otherfraction.numer 24 | newden = self.denom * otherfraction.denom 25 | common = gcd(newnum,newden) 26 | return Fraction(newnum//common,newden//common) 27 | 28 | def __eq__(self, other): 29 | firstnum = self.numer * other.denom 30 | secondnum = other.numer * self.denom 31 | 32 | return firstnum == secondnum 33 | def __sub__(self, otherfrac): 34 | subnum = self.numer*otherfrac.denom - \ 35 | self.denom*otherfrac.numer 36 | subden = otherfrac.denom*self.denom 37 | commonsub = gcd(subnum, subden) 38 | return Fraction(subnum//commonsub, subden//commonsub) 39 | 40 | 41 | 42 | x = Fraction(1,2) 43 | y = Fraction(2,3) 44 | print(x+y) 45 | print(x == y) 46 | print(x - y) -------------------------------------------------------------------------------- /OOP_Class.py: -------------------------------------------------------------------------------- 1 | def gcd(m,n): 2 | while m%n != 0: 3 | oldm = m 4 | oldn = n 5 | 6 | m = oldn 7 | n = oldm%oldn 8 | return n 9 | 10 | class Fraction: 11 | def __init__(self,top,bottom): 12 | self.numer = top 13 | self.denom = bottom 14 | 15 | def __str__(self): 16 | return str(self.numer)+"/"+str(self.denom) 17 | 18 | def show(self): 19 | print(self.numer,"/",self.denom) 20 | 21 | def __add__(self,otherfraction): 22 | newnum = self.numer*otherfraction.denom + \ 23 | self.denom*otherfraction.numer 24 | newden = self.denom * otherfraction.denom 25 | common = gcd(newnum,newden) 26 | return Fraction(newnum//common,newden//common) 27 | 28 | def __eq__(self, other): 29 | firstnum = self.numer * other.denom 30 | secondnum = other.numer * self.denom 31 | 32 | return firstnum == secondnum 33 | def __sub__(self, otherfrac): 34 | subnum = self.numer*otherfrac.denom - \ 35 | self.denom*otherfrac.numer 36 | subden = otherfrac.denom*self.denom 37 | commonsub = gcd(subnum, subden) 38 | return Fraction(subnum//commonsub, subden//commonsub) 39 | 40 | 41 | 42 | x = Fraction(1,2) 43 | y = Fraction(2,3) 44 | print(x+y) 45 | print(x == y) 46 | print(x - y) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Pythonic-Algorithm-Implementations 2 | ================================== 3 | 4 | Implementation of basic algorithms in Python, including error handling and basic OOP concepts. 5 | -------------------------------------------------------------------------------- /Recursion/Int_to_str_rec.py: -------------------------------------------------------------------------------- 1 | def conv_rec(target, base): 2 | samplestr = "0123456789ABCDEF" 3 | 4 | if target < base: 5 | return samplestr[target] 6 | else: 7 | return conv_rec(target//base, base) + samplestr[target%base] 8 | 9 | 10 | print(conv_rec(1453,16)) 11 | print type(conv_rec(675, 10)) -------------------------------------------------------------------------------- /Recursion/Palin_rec.py: -------------------------------------------------------------------------------- 1 | ##Yippee, I've managed to pull off a one liner this time. 2 | 3 | #Recursion implementation of a palindrome checker. 4 | 5 | def palin_rec(target): 6 | return (not target) or (target.lower()[0] == target.lower()[-1] and palin_rec(target.lower()[1:-1])) 7 | 8 | 9 | # print palin_rec("Malayalam") -------------------------------------------------------------------------------- /Recursion/Reverse_String_rec.py: -------------------------------------------------------------------------------- 1 | def rev_str(target): 2 | if len(target) == 1: 3 | return target 4 | else: 5 | return rev_str(target[1:]) + target[0] 6 | 7 | 8 | # print rev_str("Pikachu") -------------------------------------------------------------------------------- /Recursion/Sum_of_list_rec.py: -------------------------------------------------------------------------------- 1 | def sum_rec(target): 2 | if len(target) == 1: 3 | return target[0] 4 | else: 5 | return target[0] + sum_rec(target[1:]) 6 | 7 | 8 | #So, the code breaks the list recursively and compute the sum 9 | #Ex: [3,5,7,9] is broken into (3 + (5 + (7 + 9))) and the ones in side the parantheses are solved 10 | #stepwise. 11 | 12 | 13 | #print sum_rec([1,3,5,7,9]) -------------------------------------------------------------------------------- /Recursion/Turtle_Vis/Spiral_rec.py: -------------------------------------------------------------------------------- 1 | import turtle 2 | 3 | turt = turtle.Turtle() 4 | window = turtle.Screen() 5 | 6 | def spiral_rec(turt, line): 7 | if line > 0: 8 | turt.forward(line) 9 | turt.right(45) 10 | spiral_rec(turt, line - 3) 11 | 12 | 13 | # spiral_rec(turt, 100) 14 | # window.exitonclick() -------------------------------------------------------------------------------- /Recursion/fibo.py: -------------------------------------------------------------------------------- 1 | def fibo(n): 2 | if n == 0: 3 | return 0 4 | elif n == 1: 5 | return 1 6 | else: 7 | return fibo(n-1) + fibo(n-2) 8 | 9 | 10 | print fibo(5) -------------------------------------------------------------------------------- /Searching/Binary_Search.py: -------------------------------------------------------------------------------- 1 | def Binary_search(alist, item): 2 | 3 | first = 0 4 | last = len(alist) - 1 5 | found = False 6 | 7 | while not found and (first alist[mid]: 15 | first = mid+1 16 | if item < alist[mid]: 17 | last = mid 18 | 19 | return found 20 | 21 | 22 | testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42,] 23 | print(Binary_search(testlist, 8)) 24 | -------------------------------------------------------------------------------- /Searching/Binary_Search_OL.py: -------------------------------------------------------------------------------- 1 | def binary_search_ol(alist, item): 2 | if len(alist) == 0: 3 | return False 4 | else: 5 | mid = len(alist)//2 6 | if alist[mid] == item: 7 | return True 8 | else: 9 | if item item: 11 | stop = True 12 | else: 13 | pos += 1 14 | 15 | return found 16 | 17 | alist2 = [1,5,35,7,23] 18 | print seq_search_OL(alist2,35) 19 | -------------------------------------------------------------------------------- /Trees/bin_tree.py: -------------------------------------------------------------------------------- 1 | def BinaryTree(r): 2 | return [r, [], []] 3 | 4 | def insertLeft(root,newBranch): 5 | t = root.pop(1) 6 | if len(t) > 1: 7 | root.insert(1,[newBranch,t,[]]) 8 | else: 9 | root.insert(1,[newBranch, [], []]) 10 | return root 11 | 12 | def insertRight(root,newBranch): 13 | t = root.pop(2) 14 | if len(t) > 1: 15 | root.insert(2,[newBranch,[],t]) 16 | else: 17 | root.insert(2,[newBranch,[],[]]) 18 | return root 19 | 20 | def getRootVal(root): 21 | return root[0] 22 | 23 | def setRootVal(root,newVal): 24 | root[0] = newVal 25 | 26 | def getLeftChild(root): 27 | return root[1] 28 | 29 | def getRightChild(root): 30 | return root[2] 31 | 32 | r = BinaryTree(3) 33 | insertLeft(r,4) 34 | insertLeft(r,5) 35 | insertRight(r,6) 36 | insertRight(r,7) 37 | l = getLeftChild(r) 38 | print(l) 39 | 40 | setRootVal(l,9) 41 | print(r) 42 | insertLeft(l,11) 43 | print(r) 44 | print(getRightChild(getRightChild(r))) 45 | --------------------------------------------------------------------------------