diff --git a/BinaryToDecimal.py b/BinaryToDecimal.py index 1c3096c8..7587d2a8 100644 --- a/BinaryToDecimal.py +++ b/BinaryToDecimal.py @@ -20,15 +20,30 @@ def decToBin(decNum): #function created to convert decimal to binary with parame return binNum def convert(fromNum, fromBase, toBase): #function for converting from any base to any other base + # Step 1: Convert fromNum (represented as an integer using digits of fromBase) to a standard base 10 integer + val = 0 + power = 0 + temp = fromNum + while temp > 0: + digit = temp % 10 + if digit >= fromBase: + raise ValueError(f"Digit {digit} is invalid for base {fromBase}") + val += digit * (fromBase ** power) + temp //= 10 + power += 1 + + # Step 2: Convert standard base 10 integer to the target base (represented using base 10 digits) toNum = 0 power = 0 - while fromNum > 0: - toNum += fromBase ** power * (fromNum % toBase) - fromNum //= toBase + while val > 0: + digit = val % toBase + toNum += digit * (10 ** power) + val //= toBase power += 1 return toNum -# print (str(binToDec(101011))) -# print (str(decToBin(128))) -print (str(convert(127, 10, 8))) # converts 127 in base 10 to base 8 -print (str(convert(101001, 2, 2))) +print("101011 in base 2 to base 10: " + str(binToDec(101011))) +print("128 in base 10 to base 2: " + str(decToBin(128))) +print("127 in base 10 to base 8: " + str(convert(127, 10, 8))) # converts 127 in base 10 to base 8 +print("177 in base 8 to base 2: " + str(convert(177, 8, 2))) # converts 177 in base 8 to base 2 + diff --git a/DepthFirstSearch.py b/DepthFirstSearch.py index 9c5498ba..84212e5c 100644 --- a/DepthFirstSearch.py +++ b/DepthFirstSearch.py @@ -13,8 +13,9 @@ def add_neighbor(self, v): self.neighbors.sort() class Graph: - vertices = {} - time = 0 + def __init__(self): + self.vertices = {} + self.time = 0 def add_vertex(self, vertex): if isinstance(vertex, Vertex) and vertex.name not in self.vertices: @@ -39,20 +40,18 @@ def print_graph(self): print(key + str(self.vertices[key].neighbors) + " " + str(self.vertices[key].discovery) + "/" + str(self.vertices[key].finish)) def _dfs(self, vertex): - global time vertex.color = 'red' - vertex.discovery = time - time += 1 + vertex.discovery = self.time + self.time += 1 for v in vertex.neighbors: if self.vertices[v].color == 'black': self._dfs(self.vertices[v]) vertex.color = 'blue' - vertex.finish = time - time += 1 + vertex.finish = self.time + self.time += 1 def dfs(self, vertex): - global time - time = 1 + self.time = 1 self._dfs(vertex) g = Graph() diff --git a/HashMap.py b/HashMap.py index c5808e00..655b6fc5 100644 --- a/HashMap.py +++ b/HashMap.py @@ -49,7 +49,8 @@ def keys(self): arr = [] for i in range(0, len(self.map)): if self.map[i]: - arr.append(self.map[i][0]) + for pair in self.map[i]: + arr.append(pair[0]) return arr def print(self): diff --git a/HexToDec.py b/HexToDec.py index 2b289400..fa953e4f 100644 --- a/HexToDec.py +++ b/HexToDec.py @@ -1,18 +1,22 @@ # Python Hexadecimal to Decimal Conversion def __getDecDigit(digit): - digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F'] - for x in range(len(digits)): - if digit == digits[x]: - return x + digits = { + '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, + 'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15 + } + return digits.get(digit.upper()) def hexToDec(hexNum): decNum = 0 power = 0 for digit in range(len(hexNum), 0, -1): - decNum = decNum + 16 ** power * __getDecDigit(hexNum[digit-1]) + val = __getDecDigit(hexNum[digit-1]) + if val is None: + raise ValueError(f"Invalid hexadecimal digit: {hexNum[digit-1]}") + decNum = decNum + 16 ** power * val power += 1 - print(str(decNum)) + return decNum -hexToDec("A5") \ No newline at end of file +print("A5 in decimal: " + str(hexToDec("A5"))) +print("3c in decimal: " + str(hexToDec("3c"))) \ No newline at end of file diff --git a/MaxHeap.py b/MaxHeap.py index 0168aae5..e1abd73a 100644 --- a/MaxHeap.py +++ b/MaxHeap.py @@ -3,19 +3,20 @@ # private functions: __swap, __floatUp, __bubbleDown class MaxHeap: - def __init__(self, items=[]): + def __init__(self, items=None): super().__init__() self.heap = [0] - for i in items: - self.heap.append(i) - self.__floatUp(len(self.heap) - 1) + if items is not None: + for i in items: + self.heap.append(i) + self.__floatUp(len(self.heap) - 1) def push(self, data): self.heap.append(data) self.__floatUp(len(self.heap) - 1) def peek(self): - if self.heap[1]: + if len(self.heap) > 1: return self.heap[1] else: return False @@ -56,5 +57,15 @@ def __bubbleDown(self, index): m = MaxHeap([95, 3, 21]) m.push(10) -print(str(m.heap[0:len(m.heap)])) -print(str(m.pop())) \ No newline at end of file +print("Heap state:", m.heap) +print("Peek top:", m.peek()) +print("Popped:", m.pop()) +print("Peek top after pop:", m.peek()) + +# Test empty heap peek +empty_heap = MaxHeap() +print("Empty heap peek:", empty_heap.peek()) + +# Test heap with 0 +heap_with_zero = MaxHeap([0]) +print("Zero heap peek:", heap_with_zero.peek()) \ No newline at end of file diff --git a/Queues implementaion.py b/Queues implementaion.py deleted file mode 100644 index 63170c8c..00000000 --- a/Queues implementaion.py +++ /dev/null @@ -1,64 +0,0 @@ - -# implemented by Linked list -class Node(object): - def __init__(self, item = None): - self.item = item - self.next = None - self.previous = None - - -class Queue(object): - def __init__(self): - self.length = 0 - self.head = None - self.tail = None - - def enqueue(self, x): - newNode = Node(x) - if self.head == None: - self.head = self.tail = newNode - else: - self.tail.next = newNode - newNode.previous = self.tail - self.tail = newNode - self.length += 1 - - - def dequeue (self): - item = self.head.item - self.head = self.head.next - self.length -= 1 - if self.length == 0: - self.last = None - return item - - -################################################# - -# implemented by array -class Queue: - def __init__(self): - self.items = [] - - def is_empty(self): - return self.items == [] - - def enqueue(self, data): - self.items.append(data) - - def dequeue(self): - return self.items.pop(0) - - def display(self): - ar = [] - for i in self.items: - ar.append(i) - return ar -que = Queue() -que.enqueue('google') -que.enqueue('youtube') -que.enqueue('udemy') -que.enqueue('udacity') -que.dequeue() -que.dequeue() -print(que.display()) diff --git a/Queues_implementation.py b/Queues_implementation.py new file mode 100644 index 00000000..027be3d5 --- /dev/null +++ b/Queues_implementation.py @@ -0,0 +1,116 @@ +# Queue Implementation in Python +# This file includes two queue implementations: +# 1. LinkedListQueue: using a custom Node class. +# 2. ArrayQueue: using Python's built-in list. + +class Node: + """A class representing a node in a linked list queue.""" + def __init__(self, item=None): + self.item = item + self.next = None + self.previous = None + + +class LinkedListQueue: + """A Queue implementation using a doubly linked list.""" + def __init__(self): + self.length = 0 + self.head = None + self.tail = None + + def enqueue(self, x): + """Add an element to the back of the queue.""" + new_node = Node(x) + if self.head is None: + self.head = self.tail = new_node + else: + self.tail.next = new_node + new_node.previous = self.tail + self.tail = new_node + self.length += 1 + + def dequeue(self): + """Remove and return the front element of the queue.""" + if self.is_empty(): + raise IndexError("dequeue from empty queue") + item = self.head.item + self.head = self.head.next + if self.head is not None: + self.head.previous = None + self.length -= 1 + if self.length == 0: + self.tail = None + return item + + def is_empty(self): + """Return True if the queue is empty, False otherwise.""" + return self.length == 0 + + def size(self): + """Return the number of elements in the queue.""" + return self.length + + def display(self): + """Return a list representation of the queue from front to back.""" + arr = [] + current = self.head + while current: + arr.append(current.item) + current = current.next + return arr + + +class ArrayQueue: + """A Queue implementation using a dynamic array (Python list).""" + def __init__(self): + self.items = [] + + def is_empty(self): + """Return True if the queue is empty, False otherwise.""" + return len(self.items) == 0 + + def enqueue(self, data): + """Add an element to the back of the queue.""" + self.items.append(data) + + def dequeue(self): + """Remove and return the front element of the queue.""" + if self.is_empty(): + raise IndexError("dequeue from empty queue") + return self.items.pop(0) + + def size(self): + """Return the number of elements in the queue.""" + return len(self.items) + + def display(self): + """Return a list representation of the queue from front to back.""" + return list(self.items) + + +def main(): + print("--- Testing ArrayQueue ---") + que = ArrayQueue() + que.enqueue('google') + que.enqueue('youtube') + que.enqueue('udemy') + que.enqueue('udacity') + print("Initial queue:", que.display()) + print("Dequeued:", que.dequeue()) + print("Dequeued:", que.dequeue()) + print("Remaining queue:", que.display()) + + print("\n--- Testing LinkedListQueue ---") + ll_que = LinkedListQueue() + ll_que.enqueue('google') + ll_que.enqueue('youtube') + ll_que.enqueue('udemy') + ll_que.enqueue('udacity') + print("Initial queue:", ll_que.display()) + print("Dequeued:", ll_que.dequeue()) + print("Dequeued:", ll_que.dequeue()) + print("Remaining queue:", ll_que.display()) + + +if __name__ == "__main__": + main() diff --git a/README.md b/README.md index 939de1ed..aa6e9c42 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,20 @@ -#This is a open source project. -# Python 3 -These files are mainly intended to accompany my series of YouTube tutorial videos here, +# Python 3 Examples + +This is an open source project. These files are mainly intended to accompany my series of YouTube tutorial videos here: https://www.youtube.com/user/joejamesusa -and are mainly intended for educational purposes. -You are invited to subscribe to my video channel-Joe James, and to download and use any code in -this Python repository, according to the MIT License. -Feel free to post any comments on my YouTube channel. -I am very happy to see you there on my you tube channel. excited!!!!!!!!! -## Subscribe to my channel for more tutorial videos. - -This source code is easy to understand and reliable for self study and you will learn them easily, try to practice more coding by making algorithms yourself and you can become a better Python programmer, and remember "Try to learn something about everything and everything about something". - -Thank you for reviewing my repositories and keep practicing. -Joe James. -Fremont, CA. + +The examples are mainly intended for educational purposes. You are invited to subscribe to my video channel (Joe James) and to download and use any code in this Python repository according to the MIT License. Feel free to post any comments on my YouTube channel. + +I am very happy to see you there on my YouTube channel! + +## Subscribe to my channel for more tutorial videos + +This source code is easy to understand and reliable for self-study, helping you learn concepts easily. Try to practice more coding by designing algorithms yourself to become a better Python programmer. Remember: "Try to learn something about everything and everything about something." + +Thank you for reviewing my repository, and keep practicing! + +Joe James +Fremont, CA Copyright (C) 2015-2021, Joe James -## Happy coding guys!😀 +## Happy coding! 💻 diff --git a/Stack.py b/Stack.py new file mode 100644 index 00000000..5124a7bb --- /dev/null +++ b/Stack.py @@ -0,0 +1,123 @@ +# Stack Implementation in Python +# This file includes two stack implementations: +# 1. ArrayStack: using Python's built-in list. +# 2. LinkedListStack: using a custom Node class. + +class Node: + """A class representing a node in a linked list stack.""" + def __init__(self, data, next_node=None): + self.data = data + self.next_node = next_node + + +class LinkedListStack: + """A Stack implementation using a singly linked list.""" + def __init__(self): + self.head = None + self._size = 0 + + def push(self, data): + """Push an element onto the stack.""" + new_node = Node(data, self.head) + self.head = new_node + self._size += 1 + + def pop(self): + """Pop and return the top element of the stack. Raise IndexError if empty.""" + if self.is_empty(): + raise IndexError("pop from empty stack") + popped_node = self.head + self.head = self.head.next_node + self._size -= 1 + return popped_node.data + + def peek(self): + """Return the top element without removing it. Raise IndexError if empty.""" + if self.is_empty(): + raise IndexError("peek on empty stack") + return self.head.data + + def is_empty(self): + """Return True if the stack is empty, False otherwise.""" + return self.head is None + + def size(self): + """Return the number of elements in the stack.""" + return self._size + + def __str__(self): + """Return a string representation of the stack.""" + elements = [] + current = self.head + while current: + elements.append(repr(current.data)) + current = current.next_node + return "Top -> " + " -> ".join(elements) if elements else "Empty Stack" + + +class ArrayStack: + """A Stack implementation using a dynamic array (Python list).""" + def __init__(self): + self.items = [] + + def push(self, data): + """Push an element onto the stack.""" + self.items.append(data) + + def pop(self): + """Pop and return the top element of the stack. Raise IndexError if empty.""" + if self.is_empty(): + raise IndexError("pop from empty stack") + return self.items.pop() + + def peek(self): + """Return the top element without removing it. Raise IndexError if empty.""" + if self.is_empty(): + raise IndexError("peek on empty stack") + return self.items[-1] + + def is_empty(self): + """Return True if the stack is empty, False otherwise.""" + return len(self.items) == 0 + + def size(self): + """Return the number of elements in the stack.""" + return len(self.items) + + def __str__(self): + """Return a string representation of the stack.""" + return "Bottom -> " + str(self.items) + " <- Top" + + +def main(): + print("--- Testing ArrayStack ---") + array_stack = ArrayStack() + print(f"Is empty? {array_stack.is_empty()}") + + array_stack.push("Google") + array_stack.push("YouTube") + array_stack.push("Udemy") + + print(array_stack) + print(f"Stack size: {array_stack.size()}") + print(f"Peek top: {array_stack.peek()}") + print(f"Popped: {array_stack.pop()}") + print(array_stack) + + print("\n--- Testing LinkedListStack ---") + ll_stack = LinkedListStack() + print(f"Is empty? {ll_stack.is_empty()}") + + ll_stack.push(10) + ll_stack.push(20) + ll_stack.push(30) + + print(ll_stack) + print(f"Stack size: {ll_stack.size()}") + print(f"Peek top: {ll_stack.peek()}") + print(f"Popped: {ll_stack.pop()}") + print(ll_stack) + + +if __name__ == "__main__": + main() diff --git a/TempConversion.py b/TempConversion.py index b8c71e54..72eae49b 100644 --- a/TempConversion.py +++ b/TempConversion.py @@ -8,22 +8,23 @@ def menu(): return choice def toCelsius(f): - return int((f - 32) / 1.8) + return round((f - 32) / 1.8, 2) def toFahrenheit(c): - return int(c * 1.8 + 32) + return round(c * 1.8 + 32, 2) def main(): choice = menu() while choice != 3: if choice == 1: - c = eval(input("Enter degrees Celsius: ")) + c = float(input("Enter degrees Celsius: ")) print(str(c) + "C = " + str(toFahrenheit(c)) + "F") elif choice == 2: - f = eval(input("Enter degrees Fahrenheit: ")) + f = float(input("Enter degrees Fahrenheit: ")) print(str(f) + "F = " + str(toCelsius(f)) + "C") else: print("Invalid choice.") choice = menu() -main() \ No newline at end of file +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/Trees/BinarySearchTree.py b/Trees/BinarySearchTree.py index c1e34b82..d64d7415 100644 --- a/Trees/BinarySearchTree.py +++ b/Trees/BinarySearchTree.py @@ -115,7 +115,6 @@ def remove(self, data): delNodeParent = delNode delNode = delNode.leftChild - self.root.value = delNode.value if delNode.rightChild: if delNodeParent.value > delNode.value: delNodeParent.leftChild = delNode.rightChild @@ -126,6 +125,7 @@ def remove(self, data): delNodeParent.leftChild = None else: delNodeParent.rightChild = None + self.root.value = delNode.value return True @@ -176,7 +176,6 @@ def remove(self, data): delNodeParent = delNode delNode = delNode.leftChild - node.value = delNode.value if delNode.rightChild: if delNodeParent.value > delNode.value: delNodeParent.leftChild = delNode.rightChild @@ -187,6 +186,8 @@ def remove(self, data): delNodeParent.leftChild = None else: delNodeParent.rightChild = None + node.value = delNode.value + return True def preorder(self): if self.root is not None: @@ -203,12 +204,24 @@ def inorder(self): print("InOrder") self.root.inorder() -bst = Tree() -print(bst.insert(10)) -#print(bst.insert(5)) -bst.preorder() -print(bst.getHeight()) -#bst.postorder() -#bst.inorder() -print(bst.remove(10)) -bst.preorder() \ No newline at end of file +def main(): + bst = Tree() + print("Insert 10:", bst.insert(10)) + bst.preorder() + print("Height:", bst.getHeight()) + print("Removing 10:", bst.remove(10)) + bst.preorder() + + # Test removing non-root node with two children + print("\n--- Testing non-root node removal with two children ---") + t = Tree() + for val in [10, 5, 15, 2, 7, 12, 17, 11, 13, 14]: + t.insert(val) + print("Preorder before removing 12:") + t.preorder() + print("Removing 12:", t.remove(12)) + print("Preorder after removing 12:") + t.preorder() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/Trees/bst.py b/Trees/bst.py index f45b2f4f..1c43ded6 100644 --- a/Trees/bst.py +++ b/Trees/bst.py @@ -192,7 +192,6 @@ def remove(self, data): delNodeParent = delNode delNode = delNode.leftChild - node.value = delNode.value if delNode.rightChild: if delNodeParent.value > delNode.value: delNodeParent.leftChild = delNode.rightChild @@ -203,6 +202,8 @@ def remove(self, data): delNodeParent.leftChild = None else: delNodeParent.rightChild = None + node.value = delNode.value + return True def preorder(self): if self.root is not None: @@ -221,16 +222,26 @@ def inorder(self): def main(): bst = Tree() - print(bst.insert(10)) - print(bst.insert(5)) + print("Insert 10:", bst.insert(10)) + print("Insert 5:", bst.insert(5)) bst.insert(2) bst.insert(7) bst.preorder() print('Height = ', bst.getHeight()) print('Size = ', bst.getSize()) - #bst.postorder() - #bst.inorder() - print(bst.remove(10)) + print("Removing root 10:", bst.remove(10)) bst.preorder() -main() + # Test removing non-root node with two children + print("\n--- Testing non-root node removal with two children ---") + t = Tree() + for val in [10, 5, 15, 2, 7, 12, 17, 11, 13, 14]: + t.insert(val) + print("Preorder before removing 12:") + t.preorder() + print("Removing 12:", t.remove(12)) + print("Preorder after removing 12:") + t.preorder() + +if __name__ == "__main__": + main() diff --git a/__pycache__/TempConversion.cpython-311.pyc b/__pycache__/TempConversion.cpython-311.pyc new file mode 100644 index 00000000..682b13f6 Binary files /dev/null and b/__pycache__/TempConversion.cpython-311.pyc differ diff --git a/bfs.py b/bfs.py index a91468a0..47da1212 100644 --- a/bfs.py +++ b/bfs.py @@ -12,7 +12,8 @@ def add_neighbor(self, v): self.neighbors.sort() class Graph: - vertices = {} + def __init__(self): + self.vertices = {} def add_vertex(self, vertex): if isinstance(vertex, Vertex) and vertex.name not in self.vertices: @@ -40,21 +41,18 @@ def bfs(self, vert): q = list() vert.distance = 0 vert.color = 'red' - for v in vert.neighbors: - self.vertices[v].distance = vert.distance + 1 - q.append(v) + q.append(vert.name) while len(q) > 0: u = q.pop(0) node_u = self.vertices[u] - node_u.color = 'red' for v in node_u.neighbors: node_v = self.vertices[v] if node_v.color == 'black': + node_v.color = 'red' + node_v.distance = node_u.distance + 1 q.append(v) - if node_v.distance > node_u.distance + 1: - node_v.distance = node_u.distance + 1 g = Graph() a = Vertex('A') diff --git a/file_ops.py b/file_ops.py index 582ac17e..0b3144f9 100644 --- a/file_ops.py +++ b/file_ops.py @@ -1,6 +1,19 @@ +import os + infile = "inputFile.txt" outfile = "outputFile.txt" +# Create a sample input file if it does not exist +if not os.path.exists(infile): + with open(infile, "w") as f: + f.write("Ford,Mustang,2020,Red\n") + f.write("Toyota,Camry,2019,Blue\n") + f.write("Honda,Civic,2021,Black\n") + +# Clean up previous output file if exists to prevent accumulation across runs +if os.path.exists(outfile): + os.remove(outfile) + # print each line, as read in with open(infile) as f1: for line in f1: diff --git a/gcf.py b/gcf.py index 48bd673f..c58fc7d6 100644 --- a/gcf.py +++ b/gcf.py @@ -1,13 +1,10 @@ # computes Greatest Common Factor GCF / Greatest Common Divisor GCD of two numbers # useful for reducing fractions -def gcf (num1, num2): - if num1 > num2: - num1, num2 = num2, num1 - - for x in range (num1, 0, -1): - if num1 % x == 0 and num2 % x == 0: - return x +def gcf(num1, num2): + while num2: + num1, num2 = num2, num1 % num2 + return num1 num1 = 18 num2 = 204 diff --git a/inputFile.txt b/inputFile.txt new file mode 100644 index 00000000..b2451472 --- /dev/null +++ b/inputFile.txt @@ -0,0 +1,3 @@ +Ford,Mustang,2020,Red +Toyota,Camry,2019,Blue +Honda,Civic,2021,Black diff --git a/outputFile.txt b/outputFile.txt new file mode 100644 index 00000000..baca4dca --- /dev/null +++ b/outputFile.txt @@ -0,0 +1,6 @@ +Ford +Toyota +Honda +['Ford', 'Mustang', '2020', 'Red\n'] +['Toyota', 'Camry', '2019', 'Blue\n'] +['Honda', 'Civic', '2021', 'Black\n'] diff --git a/remove_from_list.py b/remove_from_list.py index 9619664f..cd3b7422 100644 --- a/remove_from_list.py +++ b/remove_from_list.py @@ -37,7 +37,10 @@ def get_dogs(): dogs = get_dogs() print('6. del entire list:') del(dogs) -print(dogs) +try: + print(dogs) +except NameError: + print("NameError: 'dogs' is no longer defined (successfully deleted)")