├── Automate the Boring Stuff with Python.pdf ├── Data-Structures ├── avl_tree │ ├── avl_tree.py │ └── test_avl_tree.py ├── binary_search_tree │ ├── binary_search_tree.py │ └── test_binary_search_tree.py ├── doubly_linked_list │ ├── doubly_linked_list.py │ └── test_doubly_linked_list.py ├── heap │ ├── README.md │ ├── generic_heap.py │ ├── max_heap.py │ ├── test_generic_heap.py │ └── test_max_heap.py ├── lru_cache │ ├── lru_cache.py │ └── test_lru_cache.py ├── queue │ ├── queue.py │ └── test_queue.py ├── singly_linked_list │ ├── singly_linked_list.py │ └── test_singly_linked_list.py └── stack │ ├── singly_linked_list.py │ ├── stack.py │ └── test_stack.py ├── Python Playground - Mahesh Venkitachalam.pdf ├── README.md ├── adventure game ├── adv.py ├── player.py └── room.py ├── eating_cookies ├── README.md ├── eating_cookies.py └── test_eating_cookies.py ├── examples games ├── guessing_game.py ├── history.txt └── rock_paper_scissors.py ├── iterative_sorting ├── README.md ├── iterative_sorting.py └── test_iterative.py ├── names ├── names.py ├── names_1.txt └── names_2.txt ├── python-crash-course.pdf ├── reverse ├── reverse.py └── test_reverse.py ├── ring_buffer ├── ring_buffer.py └── test_ring_buffer.py ├── searching ├── README.md ├── searching.py └── test_searching.py ├── small bits ├── 00_hello.py ├── 01_bignum.py ├── 02_datatypes.py ├── 03_modules.py ├── 04_printing.py ├── 05_lists.py ├── 06_tuples.py ├── 07_slices.py ├── 08_comprehensions.py ├── 09_dictionaries.py ├── 10_functions.py ├── 11_args.py ├── 12_scopes.py ├── 13_file_io.py ├── 14_cal.py ├── 15_classes.py ├── bar.txt └── foo.txt └── small programs ├── cityreader ├── cities.csv ├── cityreader.py ├── test_cityreader.py └── test_stretch.py ├── comp ├── comp.py └── test_comp.py └── oop ├── oop1.py ├── oop2.py ├── test_oop1.py └── test_oop2.py /Automate the Boring Stuff with Python.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValeriiaMur/Python-books-and-exercises/fdc2cf8399906f138e9307bb8f77082d05d81094/Automate the Boring Stuff with Python.pdf -------------------------------------------------------------------------------- /Data-Structures/avl_tree/avl_tree.py: -------------------------------------------------------------------------------- 1 | """ 2 | Node class to keep track of 3 | the data internal to individual nodes 4 | """ 5 | class Node: 6 | def __init__(self, key): 7 | self.key = key 8 | self.left = None 9 | self.right = None 10 | 11 | """ 12 | A tree class to keep track of things like the 13 | balance factor and the rebalancing logic 14 | """ 15 | class AVLTree: 16 | def __init__(self, node=None): 17 | self.node = node 18 | # init height to -1 because of 0-indexing 19 | self.height = -1 20 | self.balance = 0 21 | 22 | """ 23 | Display the whole tree. Uses recursive def. 24 | """ 25 | def display(self, level=0, pref=''): 26 | self.update_height() # Update height before balancing 27 | self.update_balance() 28 | 29 | if self.node != None: 30 | print ('-' * level * 2, pref, self.node.key, 31 | f'[{self.height}:{self.balance}]', 32 | 'L' if self.height == 0 else ' ') 33 | if self.node.left != None: 34 | self.node.left.display(level + 1, '<') 35 | if self.node.right != None: 36 | self.node.right.display(level + 1, '>') 37 | 38 | """ 39 | Computes the maximum number of levels there are 40 | in the tree 41 | """ 42 | def update_height(self): 43 | pass 44 | 45 | """ 46 | Updates the balance factor on the AVLTree class 47 | """ 48 | def update_balance(self): 49 | pass 50 | 51 | """ 52 | Perform a left rotation, making the right child of this 53 | node the parent and making the old parent the left child 54 | of the new parent. 55 | """ 56 | def left_rotate(self): 57 | pass 58 | 59 | """ 60 | Perform a right rotation, making the left child of this 61 | node the parent and making the old parent the right child 62 | of the new parent. 63 | """ 64 | def right_rotate(self): 65 | pass 66 | 67 | """ 68 | Sets in motion the rebalancing logic to ensure the 69 | tree is balanced such that the balance factor is 70 | 1 or -1 71 | """ 72 | def rebalance(self): 73 | pass 74 | 75 | """ 76 | Uses the same insertion logic as a binary search tree 77 | after the value is inserted, we need to check to see 78 | if we need to rebalance 79 | """ 80 | def insert(self, key): 81 | pass 82 | -------------------------------------------------------------------------------- /Data-Structures/avl_tree/test_avl_tree.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from avl_tree import AVLTree 3 | from avl_tree import Node 4 | 5 | class AVLTreeTests(unittest.TestCase): 6 | def setUp(self): 7 | self.tree = AVLTree() 8 | 9 | def test_update_height(self): 10 | self.assertEqual(self.tree.height, -1) 11 | self.tree.node = Node(5) 12 | self.tree.update_height() 13 | self.assertEqual(self.tree.height, 0) 14 | 15 | self.tree.node.left = AVLTree(Node(3)) 16 | self.tree.update_height() 17 | self.assertEqual(self.tree.node.left.height, 0) 18 | self.assertEqual(self.tree.height, 1) 19 | 20 | self.tree.node.right = AVLTree(Node(6)) 21 | self.tree.update_height() 22 | self.assertEqual(self.tree.height, 1) 23 | 24 | self.tree.node.right.node.right = AVLTree(Node(8)) 25 | self.tree.update_height() 26 | self.assertEqual(self.tree.height, 2) 27 | 28 | def test_left_rotation(self): 29 | self.tree.node = Node(5) 30 | self.tree.node.left = AVLTree(Node('x')) 31 | self.tree.node.right = AVLTree(Node(8)) 32 | self.tree.node.right.node.left = AVLTree(Node('c')) 33 | self.tree.node.right.node.right = AVLTree(Node(9)) 34 | self.tree.node.right.node.right.node.left = AVLTree(Node('y')) 35 | self.tree.node.right.node.right.node.right = AVLTree(Node('z')) 36 | 37 | self.tree.left_rotate() 38 | 39 | self.assertEqual(self.tree.node.key, 8) 40 | self.assertEqual(self.tree.node.left.node.key, 5) 41 | self.assertEqual(self.tree.node.right.node.key, 9) 42 | self.assertEqual(self.tree.node.left.node.left.node.key, 'x') 43 | self.assertEqual(self.tree.node.left.node.right.node.key, 'c') 44 | self.assertEqual(self.tree.node.right.node.left.node.key, 'y') 45 | self.assertEqual(self.tree.node.right.node.right.node.key, 'z') 46 | 47 | def test_right_rotation(self): 48 | self.tree.node = Node(5) 49 | self.tree.node.right = AVLTree(Node('x')) 50 | self.tree.node.left = AVLTree(Node(4)) 51 | self.tree.node.left.node.right = AVLTree(Node('c')) 52 | self.tree.node.left.node.left = AVLTree(Node(3)) 53 | self.tree.node.left.node.left.node.left = AVLTree(Node('y')) 54 | self.tree.node.left.node.left.node.right = AVLTree(Node('z')) 55 | 56 | self.tree.right_rotate() 57 | 58 | self.assertEqual(self.tree.node.key, 4) 59 | self.assertEqual(self.tree.node.left.node.key, 3) 60 | self.assertEqual(self.tree.node.right.node.key, 5) 61 | self.assertEqual(self.tree.node.left.node.left.node.key, 'y') 62 | self.assertEqual(self.tree.node.left.node.right.node.key, 'z') 63 | self.assertEqual(self.tree.node.right.node.left.node.key, 'c') 64 | self.assertEqual(self.tree.node.right.node.right.node.key, 'x') 65 | 66 | def test_rebalancing(self): 67 | self.tree.node = Node(5) 68 | self.tree.node.right = AVLTree(Node('x')) 69 | self.tree.node.left = AVLTree(Node(3)) 70 | self.tree.node.left.node.right = AVLTree(Node(4)) 71 | self.tree.node.left.node.left = AVLTree(Node('c')) 72 | self.tree.node.left.node.right.node.left = AVLTree(Node('y')) 73 | self.tree.node.left.node.right.node.right = AVLTree(Node('z')) 74 | 75 | self.tree.rebalance() 76 | 77 | self.assertEqual(self.tree.node.key, 4) 78 | self.assertEqual(self.tree.node.left.node.key, 3) 79 | self.assertEqual(self.tree.node.right.node.key, 5) 80 | self.assertEqual(self.tree.node.left.node.left.node.key, 'c') 81 | self.assertEqual(self.tree.node.left.node.right.node.key, 'y') 82 | self.assertEqual(self.tree.node.right.node.left.node.key, 'z') 83 | self.assertEqual(self.tree.node.right.node.right.node.key, 'x') 84 | 85 | def test_insertion(self): 86 | self.tree.insert(5) 87 | self.assertEqual(self.tree.node.key, 5) 88 | 89 | self.tree.insert(3) 90 | self.assertEqual(self.tree.node.left.node.key, 3) 91 | 92 | self.tree.insert(6) 93 | self.assertEqual(self.tree.node.right.node.key, 6) 94 | 95 | self.tree.insert(7) 96 | self.assertEqual(self.tree.node.right.node.right.node.key, 7) 97 | 98 | self.tree.insert(8) 99 | self.assertEqual(self.tree.node.right.node.key, 7) 100 | self.assertEqual(self.tree.node.right.node.left.node.key, 6) 101 | self.assertEqual(self.tree.node.right.node.right.node.key, 8) 102 | 103 | if __name__ == '__main__': 104 | unittest.main() -------------------------------------------------------------------------------- /Data-Structures/binary_search_tree/binary_search_tree.py: -------------------------------------------------------------------------------- 1 | """ 2 | Binary search trees are a data structure that enforce an ordering over 3 | the data they store. That ordering in turn makes it a lot more efficient 4 | at searching for a particular piece of data in the tree. 5 | 6 | This part of the project comprises two days: 7 | 1. Implement the methods `insert`, `contains`, `get_max`, and `for_each` 8 | on the BSTNode class. 9 | 2. Implement the `in_order_print`, `bft_print`, and `dft_print` methods 10 | on the BSTNode class. 11 | """ 12 | class BSTNode: 13 | def __init__(self, value): 14 | self.value = value 15 | self.left = None 16 | self.right = None 17 | 18 | # Insert the given value into the tree 19 | def insert(self, value): 20 | #RECURSIVE PLAN 21 | #if value < root 22 | #if left child is none 23 | #add here 24 | #else 25 | #if value >= root(dupes to right) 26 | #if right child is none 27 | #add here 28 | #else 29 | #recursive call 30 | if value < self.value: 31 | if self.left is None: 32 | self.left = BSTNode(value) 33 | else: 34 | self.left.insert(value) 35 | 36 | if value >= self.value: 37 | if self.right is None: 38 | self.right = BSTNode(value) 39 | else: 40 | self.right.insert(value) 41 | 42 | 43 | #ITERATIVE PLAN 44 | #while not at the botttom, keep going 45 | #go left 46 | #if the left child is none, 47 | # add here 48 | #exit loop 49 | 50 | #go right, same values go right too 51 | #if right child is none 52 | #add here 53 | #exit loop 54 | 55 | 56 | # Return True if the tree contains the value 57 | # False if it does not 58 | def contains(self, target): 59 | if self.value is target: 60 | return True 61 | elif self.right == None and self.left == None: 62 | return False 63 | elif self.value > target: 64 | return self.left.contains(target) 65 | else: 66 | return self.right.contains(target) 67 | # else: 68 | # #go left 69 | # if target < self.value: 70 | # if self.left is target: 71 | # return True 72 | # else: 73 | # self.contains(target) 74 | 75 | # #go right 76 | # elif target >= self.value: 77 | # if self.right is target: 78 | # return True 79 | # else: 80 | # self.contains(target) 81 | # return False 82 | 83 | # Return the maximum value found in the tree 84 | def get_max(self): 85 | #go right until you cannot, return max 86 | if self.right is None: 87 | return self.value 88 | else: 89 | return self.right.get_max() 90 | 91 | 92 | # Call the function `fn` on the value of each node 93 | def for_each(self, fn): 94 | #one side than other 95 | #call fun(value) 96 | fn(self.value) 97 | 98 | #base 99 | if self.left is None and self.right is None: 100 | return 101 | 102 | #Recursive 103 | if self.left: 104 | self.left.for_each(fn) 105 | if self.right: 106 | self.right.for_each(fn) 107 | 108 | # Part 2 ----------------------- 109 | 110 | # Print all the values in order from low to high 111 | # Hint: Use a recursive, depth first traversal 112 | def in_order_print(self): 113 | pass 114 | 115 | # Print the value of every node, starting with the given node, 116 | # in an iterative breadth first traversal 117 | def bft_print(self): 118 | pass 119 | 120 | # Print the value of every node, starting with the given node, 121 | # in an iterative depth first traversal 122 | def dft_print(self): 123 | nodes = [] 124 | nodes.push(self.value) 125 | 126 | 127 | # Stretch Goals ------------------------- 128 | # Note: Research may be required 129 | 130 | # Print Pre-order recursive DFT 131 | def pre_order_dft(self): 132 | pass 133 | 134 | # Print Post-order recursive DFT 135 | def post_order_dft(self): 136 | pass 137 | 138 | def in_order_dft(self): 139 | pass 140 | 141 | """ 142 | This code is necessary for testing the `print` methods 143 | """ 144 | bst = BSTNode(1) 145 | 146 | bst.insert(8) 147 | bst.insert(5) 148 | bst.insert(7) 149 | bst.insert(6) 150 | bst.insert(3) 151 | bst.insert(4) 152 | bst.insert(2) 153 | 154 | bst.bft_print() 155 | bst.dft_print() 156 | 157 | print("elegant methods") 158 | print("pre order") 159 | bst.pre_order_dft() 160 | print("in order") 161 | bst.in_order_dft() 162 | print("post order") 163 | bst.post_order_dft() 164 | -------------------------------------------------------------------------------- /Data-Structures/binary_search_tree/test_binary_search_tree.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import random 3 | import sys 4 | import io 5 | from binary_search_tree import BSTNode 6 | 7 | class BinarySearchTreeTests(unittest.TestCase): 8 | def setUp(self): 9 | self.bst = BSTNode(5) 10 | 11 | def test_insert(self): 12 | self.bst.insert(2) 13 | self.bst.insert(3) 14 | self.bst.insert(7) 15 | self.bst.insert(6) 16 | self.assertEqual(self.bst.left.right.value, 3) 17 | self.assertEqual(self.bst.right.left.value, 6) 18 | 19 | def test_handle_dupe_insert(self): 20 | self.bst2 = BSTNode(1) 21 | self.bst2.insert(1) 22 | self.assertEqual(self.bst2.right.value, 1) 23 | 24 | def test_contains(self): 25 | self.bst.insert(2) 26 | self.bst.insert(3) 27 | self.bst.insert(7) 28 | self.assertTrue(self.bst.contains(7)) 29 | self.assertFalse(self.bst.contains(8)) 30 | 31 | def test_get_max(self): 32 | self.assertEqual(self.bst.get_max(), 5) 33 | self.bst.insert(30) 34 | self.assertEqual(self.bst.get_max(), 30) 35 | self.bst.insert(300) 36 | self.bst.insert(3) 37 | self.assertEqual(self.bst.get_max(), 300) 38 | 39 | def test_for_each(self): 40 | arr = [] 41 | cb = lambda x: arr.append(x) 42 | 43 | v1 = random.randint(1, 101) 44 | v2 = random.randint(1, 101) 45 | v3 = random.randint(1, 101) 46 | v4 = random.randint(1, 101) 47 | v5 = random.randint(1, 101) 48 | 49 | self.bst.insert(v1) 50 | self.bst.insert(v2) 51 | self.bst.insert(v3) 52 | self.bst.insert(v4) 53 | self.bst.insert(v5) 54 | 55 | self.bst.for_each(cb) 56 | 57 | self.assertTrue(5 in arr) 58 | self.assertTrue(v1 in arr) 59 | self.assertTrue(v2 in arr) 60 | self.assertTrue(v3 in arr) 61 | self.assertTrue(v4 in arr) 62 | self.assertTrue(v5 in arr) 63 | 64 | def test_print_traversals(self): 65 | # WARNING: Tests are for Print() 66 | # Debug calls to Print() in functions will cause failure 67 | 68 | stdout_ = sys.stdout # Keep previous value 69 | sys.stdout = io.StringIO() 70 | 71 | self.bst = BSTNode(1) 72 | self.bst.insert(8) 73 | self.bst.insert(5) 74 | self.bst.insert(7) 75 | self.bst.insert(6) 76 | self.bst.insert(3) 77 | self.bst.insert(4) 78 | self.bst.insert(2) 79 | 80 | self.bst.in_order_print() 81 | 82 | output = sys.stdout.getvalue() 83 | self.assertEqual(output, "1\n2\n3\n4\n5\n6\n7\n8\n") 84 | 85 | sys.stdout = io.StringIO() 86 | self.bst.bft_print() 87 | output = sys.stdout.getvalue() 88 | self.assertTrue(output == "1\n8\n5\n3\n7\n2\n4\n6\n" or 89 | output == "1\n8\n5\n7\n3\n6\n4\n2\n") 90 | 91 | sys.stdout = io.StringIO() 92 | self.bst.dft_print() 93 | output = sys.stdout.getvalue() 94 | self.assertTrue(output == "1\n8\n5\n7\n6\n3\n4\n2\n" or 95 | output == "1\n8\n5\n3\n2\n4\n7\n6\n") 96 | 97 | sys.stdout = io.StringIO() 98 | self.bst.pre_order_dft() 99 | output = sys.stdout.getvalue() 100 | self.assertEqual(output, "1\n8\n5\n3\n2\n4\n7\n6\n") 101 | 102 | sys.stdout = io.StringIO() 103 | self.bst.post_order_dft() 104 | output = sys.stdout.getvalue() 105 | self.assertEqual(output, "2\n4\n3\n6\n7\n5\n8\n1\n") 106 | 107 | sys.stdout = stdout_ # Restore stdout 108 | 109 | if __name__ == '__main__': 110 | unittest.main() 111 | -------------------------------------------------------------------------------- /Data-Structures/doubly_linked_list/doubly_linked_list.py: -------------------------------------------------------------------------------- 1 | """ 2 | Each ListNode holds a reference to its previous node 3 | as well as its next node in the List. 4 | """ 5 | class ListNode: 6 | def __init__(self, value, prev=None, next=None): 7 | self.prev = prev 8 | self.value = value 9 | self.next = next 10 | 11 | def delete(self): 12 | if self.prev: 13 | self.prev.next = self.next 14 | if self.next: 15 | self.next.prev = self.prev 16 | 17 | """ 18 | Our doubly-linked list class. It holds references to 19 | the list's head and tail nodes. 20 | """ 21 | class DoublyLinkedList: 22 | def __init__(self, node=None): 23 | self.head = node 24 | self.tail = node 25 | self.length = 1 if node is not None else 0 26 | 27 | def __len__(self): 28 | return self.length 29 | 30 | """ 31 | Wraps the given value in a ListNode and inserts it 32 | as the new head of the list. Don't forget to handle 33 | the old head node's previous pointer accordingly. 34 | """ 35 | def add_to_head(self, value): 36 | new_node = ListNode(value) 37 | if self.head is None: 38 | self.head = new_node 39 | self.tail = new_node 40 | else: 41 | new_node.next = self.head 42 | self.head.prev = new_node 43 | self.head = new_node 44 | self.length += 1 45 | 46 | 47 | """ 48 | Removes the List's current head node, making the 49 | current head's next node the new head of the List. 50 | Returns the value of the removed Node. 51 | """ 52 | def remove_from_head(self): 53 | value = self.head.value 54 | 55 | self.delete(self.head) 56 | 57 | return value 58 | 59 | 60 | """ 61 | Wraps the given value in a ListNode and inserts it 62 | as the new tail of the list. Don't forget to handle 63 | the old tail node's next pointer accordingly. 64 | """ 65 | def add_to_tail(self, value): 66 | new_node = ListNode(value) 67 | if self.head is None: 68 | self.head = new_node 69 | self.tail = new_node 70 | else: 71 | new_node.prev = self.head 72 | self.tail.next = new_node 73 | self.tail = new_node 74 | self.length += 1 75 | 76 | """ 77 | Removes the List's current tail node, making the 78 | current tail's previous node the new tail of the List. 79 | Returns the value of the removed Node. 80 | """ 81 | def remove_from_tail(self): 82 | if self.head is None: 83 | return None 84 | elif self.head is self.tail: 85 | temp = self.head.value 86 | self.head = None 87 | self.tail = None 88 | self.length -= 1 89 | return temp 90 | else: 91 | temp = self.tail 92 | self.delete(self.tail) 93 | self.tail = temp.prev 94 | self.length -= 1 95 | return temp.value 96 | 97 | 98 | """ 99 | Removes the input node from its current spot in the 100 | List and inserts it as the new head node of the List. 101 | """ 102 | def move_to_front(self, node): 103 | if node is self.head: 104 | return 105 | self.delete(node) 106 | self.add_to_head(node.value) 107 | 108 | 109 | """ 110 | Removes the input node from its current spot in the 111 | List and inserts it as the new tail node of the List. 112 | """ 113 | def move_to_end(self, node): 114 | if node is self.tail: 115 | return 116 | self.delete(node) 117 | self.add_to_tail(node.value) 118 | 119 | """ 120 | Deletes the input node from the List, preserving the 121 | order of the other elements of the List. 122 | """ 123 | def delete(self, node): 124 | #no return value, don't ipdate head and tail 125 | if self.head is None: 126 | return None 127 | elif self.head == self.tail: 128 | self.head = None 129 | self.tail = None 130 | elif node == self.head: #list has 2+ 131 | self.head = node.next 132 | node.delete() 133 | elif node == self.tail: 134 | self.tail = node.prev 135 | node.delete() 136 | else: 137 | node.delete() 138 | 139 | self.length = self.length - 1 140 | 141 | 142 | """ 143 | Finds and returns the maximum value of all the nodes 144 | in the List. 145 | """ 146 | def get_max(self): 147 | if self.head is None: 148 | return None 149 | cur_node = self.head 150 | max_value = self.head.value 151 | while cur_node: 152 | if cur_node.value > max_value: 153 | max_value = cur_node.value 154 | cur_node= cur_node.next 155 | 156 | #return max 157 | return max_value 158 | -------------------------------------------------------------------------------- /Data-Structures/doubly_linked_list/test_doubly_linked_list.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from doubly_linked_list import ListNode 3 | from doubly_linked_list import DoublyLinkedList 4 | 5 | class DoublyLinkedListTests(unittest.TestCase): 6 | def setUp(self): 7 | self.node = ListNode(1) 8 | self.dll = DoublyLinkedList(self.node) 9 | 10 | def test_list_remove_from_tail(self): 11 | self.dll.remove_from_tail() 12 | self.assertIsNone(self.dll.head) 13 | self.assertIsNone(self.dll.tail) 14 | self.assertEqual(len(self.dll), 0) 15 | 16 | self.dll.add_to_tail(33) 17 | self.assertEqual(self.dll.head.value, 33) 18 | self.assertEqual(self.dll.tail.value, 33) 19 | self.assertEqual(len(self.dll), 1) 20 | self.assertEqual(self.dll.remove_from_tail(), 33) 21 | self.assertEqual(len(self.dll), 0) 22 | 23 | self.dll.add_to_tail(68) 24 | self.assertEqual(len(self.dll), 1) 25 | self.assertEqual(self.dll.remove_from_tail(), 68) 26 | self.assertEqual(len(self.dll), 0) 27 | 28 | def test_list_remove_from_head(self): 29 | self.dll.remove_from_head() 30 | self.assertIsNone(self.dll.head) 31 | self.assertIsNone(self.dll.tail) 32 | self.assertEqual(len(self.dll), 0) 33 | 34 | self.dll.add_to_head(2) 35 | self.assertEqual(self.dll.head.value, 2) 36 | self.assertEqual(self.dll.tail.value, 2) 37 | self.assertEqual(len(self.dll), 1) 38 | self.assertEqual(self.dll.remove_from_head(), 2) 39 | self.assertEqual(len(self.dll), 0) 40 | 41 | self.dll.add_to_head(55) 42 | self.assertEqual(len(self.dll), 1) 43 | self.assertEqual(self.dll.remove_from_head(), 55) 44 | self.assertEqual(len(self.dll), 0) 45 | 46 | def test_list_add_to_tail(self): 47 | self.assertEqual(self.dll.tail.value, 1) 48 | self.assertEqual(len(self.dll), 1) 49 | 50 | self.dll.add_to_tail(30) 51 | self.assertEqual(self.dll.tail.prev.value, 1) 52 | self.assertEqual(self.dll.tail.value, 30) 53 | self.assertEqual(len(self.dll), 2) 54 | 55 | self.dll.add_to_tail(20) 56 | self.assertEqual(self.dll.tail.prev.value, 30) 57 | self.assertEqual(self.dll.tail.value, 20) 58 | self.assertEqual(len(self.dll), 3) 59 | 60 | def test_list_add_to_head(self): 61 | self.assertEqual(self.dll.head.value, 1) 62 | 63 | self.dll.add_to_head(10) 64 | self.assertEqual(self.dll.head.value, 10) 65 | self.assertEqual(self.dll.head.next.value, 1) 66 | self.assertEqual(len(self.dll), 2) 67 | 68 | def test_list_move_to_end(self): 69 | self.dll.add_to_head(40) 70 | self.assertEqual(self.dll.tail.value, 1) 71 | self.assertEqual(self.dll.head.value, 40) 72 | 73 | self.dll.move_to_end(self.dll.head) 74 | self.assertEqual(self.dll.tail.value, 40) 75 | self.assertEqual(self.dll.tail.prev.value, 1) 76 | self.assertEqual(len(self.dll), 2) 77 | 78 | self.dll.add_to_tail(4) 79 | self.dll.move_to_end(self.dll.head.next) 80 | self.assertEqual(self.dll.tail.value, 40) 81 | self.assertEqual(self.dll.tail.prev.value, 4) 82 | self.assertEqual(len(self.dll), 3) 83 | 84 | def test_list_move_to_front(self): 85 | self.dll.add_to_tail(3) 86 | self.assertEqual(self.dll.head.value, 1) 87 | self.assertEqual(self.dll.tail.value, 3) 88 | 89 | self.dll.move_to_front(self.dll.tail) 90 | self.assertEqual(self.dll.head.value, 3) 91 | self.assertEqual(self.dll.head.next.value, 1) 92 | self.assertEqual(len(self.dll), 2) 93 | 94 | self.dll.add_to_head(29) 95 | self.dll.move_to_front(self.dll.head.next) 96 | self.assertEqual(self.dll.head.value, 3) 97 | self.assertEqual(self.dll.head.next.value, 29) 98 | self.assertEqual(len(self.dll), 3) 99 | 100 | def test_list_delete(self): 101 | self.dll.delete(self.node) 102 | self.assertIsNone(self.dll.head) 103 | self.assertIsNone(self.dll.tail) 104 | self.assertEqual(len(self.dll), 0) 105 | 106 | self.dll.add_to_tail(1) 107 | self.dll.add_to_head(9) 108 | self.dll.add_to_tail(6) 109 | 110 | self.dll.delete(self.dll.head.next) 111 | self.assertEqual(self.dll.head.value, 9) 112 | self.assertEqual(self.dll.head.next, self.dll.tail) 113 | self.assertEqual(self.dll.tail.value, 6) 114 | 115 | self.dll.delete(self.dll.head) 116 | self.assertEqual(self.dll.head.value, 6) 117 | self.assertEqual(self.dll.tail.value, 6) 118 | self.assertEqual(len(self.dll), 1) 119 | 120 | self.dll.delete(self.dll.head) 121 | self.assertIsNone(self.dll.head) 122 | self.assertIsNone(self.dll.tail) 123 | self.assertEqual(len(self.dll), 0) 124 | 125 | def test_get_max(self): 126 | self.assertEqual(self.dll.get_max(), 1) 127 | self.dll.add_to_tail(100) 128 | self.assertEqual(self.dll.get_max(), 100) 129 | self.dll.add_to_tail(55) 130 | self.assertEqual(self.dll.get_max(), 100) 131 | self.dll.add_to_tail(101) 132 | self.assertEqual(self.dll.get_max(), 101) 133 | 134 | if __name__ == '__main__': 135 | unittest.main() 136 | -------------------------------------------------------------------------------- /Data-Structures/heap/README.md: -------------------------------------------------------------------------------- 1 | # Stretch Goal: Heaps 2 | 3 | ## Max Heaps 4 | * Should have the methods `insert`, `delete`, `get_max`, `_bubble_up`, and `_sift_down`. 5 | * `insert` adds the input value into the heap; this method should ensure that the inserted value is in the correct spot in the heap 6 | * `delete` removes and returns the 'topmost' value from the heap; this method needs to ensure that the heap property is maintained after the topmost element has been removed. 7 | * `get_max` returns the maximum value in the heap _in constant time_. 8 | * `get_size` returns the number of elements stored in the heap. 9 | * `_bubble_up` moves the element at the specified index "up" the heap by swapping it with its parent if the parent's value is less than the value at the specified index. 10 | * `_sift_down` grabs the indices of this element's children and determines which child has a larger value. If the larger child's value is larger than the parent's value, the child element is swapped with the parent. 11 | 12 | ![Image of a Heap in Tree form](https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Max-Heap.svg/501px-Max-Heap.svg.png) 13 | 14 | ![Image of a Heap in Array form](https://upload.wikimedia.org/wikipedia/commons/thumb/d/d2/Heap-as-array.svg/603px-Heap-as-array.svg.png) 15 | 16 | ## Generic Heaps 17 | A max heap is pretty useful, but what's even more useful is to have our heap be generic such that the user can define their own priority function and pass it to the heap to use. 18 | 19 | Augment your heap implementation so that it exhibits this behavior. If no comparator function is passed in to the heap constructor, it should default to being a max heap. Also change the name of the `get_max` function to `get_priority`. 20 | 21 | You can test your implementation against the tests in `test_generic_heap.py`. The test expects your augmented heap implementation lives in a file called `generic_heap.py`. Feel free to change the import statement to work with your file structure or copy/paste your implementation into a file with the expected name. -------------------------------------------------------------------------------- /Data-Structures/heap/generic_heap.py: -------------------------------------------------------------------------------- 1 | class Heap: 2 | # defaults to a max heap if no comparator is specified 3 | def __init__(self, comparator=lambda x, y: x > y): 4 | self.storage = [] 5 | self.comparator = comparator 6 | 7 | def insert(self, value): 8 | pass 9 | 10 | def delete(self): 11 | pass 12 | 13 | def get_priority(self): 14 | pass 15 | 16 | def get_size(self): 17 | pass 18 | 19 | def _bubble_up(self, index): 20 | pass 21 | 22 | def _sift_down(self, index): 23 | pass 24 | -------------------------------------------------------------------------------- /Data-Structures/heap/max_heap.py: -------------------------------------------------------------------------------- 1 | class Heap: 2 | def __init__(self): 3 | self.storage = [] 4 | 5 | def insert(self, value): 6 | pass 7 | 8 | def delete(self): 9 | pass 10 | 11 | def get_max(self): 12 | pass 13 | 14 | def get_size(self): 15 | pass 16 | 17 | def _bubble_up(self, index): 18 | pass 19 | 20 | def _sift_down(self, index): 21 | pass 22 | -------------------------------------------------------------------------------- /Data-Structures/heap/test_generic_heap.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from unittest.mock import MagicMock 3 | from generic_heap import Heap 4 | 5 | class HeapTests(unittest.TestCase): 6 | def setUp(self): 7 | self.heap = Heap() 8 | 9 | def test_default_heap_insert_works(self): 10 | self.heap.insert(6) 11 | self.heap.insert(8) 12 | self.heap.insert(10) 13 | self.heap.insert(9) 14 | self.heap.insert(1) 15 | self.heap.insert(9) 16 | self.heap.insert(9) 17 | self.heap.insert(5) 18 | self.assertEqual(self.heap.storage, [10, 9, 9, 6, 1, 8, 9, 5]) 19 | 20 | def test_default_get_priority_works(self): 21 | self.heap.insert(6) 22 | self.heap.insert(8) 23 | self.heap.insert(10) 24 | self.heap.insert(9) 25 | self.heap.insert(1) 26 | self.heap.insert(9) 27 | self.heap.insert(9) 28 | self.heap.insert(5) 29 | self.assertEqual(self.heap.get_size(), 8) 30 | self.assertEqual(self.heap.get_priority(), 10) 31 | 32 | def test_default_get_priority_after_delete(self): 33 | self.heap.insert(6) 34 | self.heap.insert(8) 35 | self.heap.insert(10) 36 | self.heap.insert(9) 37 | self.heap.insert(1) 38 | self.heap.insert(9) 39 | self.heap.insert(9) 40 | self.heap.insert(5) 41 | self.heap.delete() 42 | self.assertEqual(self.heap.get_priority(), 9) 43 | self.heap.delete() 44 | self.assertEqual(self.heap.get_priority(), 9) 45 | self.heap.delete() 46 | self.assertEqual(self.heap.get_priority(), 9) 47 | self.heap.delete() 48 | self.assertEqual(self.heap.get_priority(), 8) 49 | self.heap.delete() 50 | self.assertEqual(self.heap.get_priority(), 6) 51 | 52 | def test_default_delete_elements_in_order(self): 53 | self.heap.insert(6) 54 | self.heap.insert(7) 55 | self.heap.insert(5) 56 | self.heap.insert(8) 57 | self.heap.insert(10) 58 | self.heap.insert(1) 59 | self.heap.insert(2) 60 | self.heap.insert(5) 61 | 62 | descending_order = [] 63 | 64 | while self.heap.get_size() > 0: 65 | descending_order.append(self.heap.delete()) 66 | 67 | self.assertEqual(descending_order, [10, 8, 7, 6, 5, 5, 2, 1]) 68 | 69 | def test_custom_heap_insert_works(self): 70 | self.heap = Heap(lambda x, y: x < y) 71 | 72 | self.heap.insert(6) 73 | self.heap.insert(8) 74 | self.heap.insert(10) 75 | self.heap.insert(9) 76 | self.heap.insert(1) 77 | self.heap.insert(9) 78 | self.heap.insert(9) 79 | self.heap.insert(5) 80 | self.assertEqual(self.heap.storage, [1, 5, 9, 6, 8, 10, 9, 9]) 81 | 82 | def test_custom_get_priority_works(self): 83 | self.heap = Heap(lambda x, y: x < y) 84 | 85 | self.heap.insert(6) 86 | self.heap.insert(8) 87 | self.heap.insert(10) 88 | self.heap.insert(9) 89 | self.heap.insert(1) 90 | self.heap.insert(9) 91 | self.heap.insert(9) 92 | self.heap.insert(5) 93 | self.assertEqual(self.heap.get_size(), 8) 94 | self.assertEqual(self.heap.get_priority(), 1) 95 | 96 | def test_custom_get_priority_after_delete(self): 97 | self.heap = Heap(lambda x, y: x < y) 98 | 99 | self.heap.insert(6) 100 | self.heap.insert(8) 101 | self.heap.insert(10) 102 | self.heap.insert(9) 103 | self.heap.insert(1) 104 | self.heap.insert(9) 105 | self.heap.insert(9) 106 | self.heap.insert(5) 107 | self.heap.delete() 108 | self.assertEqual(self.heap.get_priority(), 5) 109 | self.heap.delete() 110 | self.assertEqual(self.heap.get_priority(), 6) 111 | self.heap.delete() 112 | self.assertEqual(self.heap.get_priority(), 8) 113 | self.heap.delete() 114 | self.assertEqual(self.heap.get_priority(), 9) 115 | self.heap.delete() 116 | self.assertEqual(self.heap.get_priority(), 9) 117 | 118 | def test_custom_delete_elements_in_order(self): 119 | self.heap = Heap(lambda x, y: x < y) 120 | 121 | self.heap.insert(6) 122 | self.heap.insert(7) 123 | self.heap.insert(5) 124 | self.heap.insert(8) 125 | self.heap.insert(10) 126 | self.heap.insert(1) 127 | self.heap.insert(2) 128 | self.heap.insert(5) 129 | 130 | ascending_order = [] 131 | 132 | while self.heap.get_size() > 0: 133 | ascending_order.append(self.heap.delete()) 134 | 135 | self.assertEqual(ascending_order, [1, 2, 5, 5, 6, 7, 8, 10]) 136 | 137 | def test_bubble_up_was_called(self): 138 | self.heap._bubble_up = MagicMock() 139 | self.heap.insert(5) 140 | self.assertTrue(self.heap._bubble_up.called) 141 | 142 | def test_sift_down_was_called(self): 143 | self.heap._sift_down = MagicMock() 144 | self.heap.insert(10) 145 | self.heap.insert(11) 146 | self.heap.delete() 147 | self.assertTrue(self.heap._sift_down.called) 148 | 149 | 150 | if __name__ == '__main__': 151 | unittest.main() 152 | -------------------------------------------------------------------------------- /Data-Structures/heap/test_max_heap.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from unittest.mock import MagicMock 3 | from max_heap import Heap 4 | 5 | 6 | class HeapTests(unittest.TestCase): 7 | def setUp(self): 8 | self.heap = Heap() 9 | 10 | def test_heap_insert_works(self): 11 | self.heap.insert(6) 12 | self.heap.insert(8) 13 | self.heap.insert(10) 14 | self.heap.insert(9) 15 | self.heap.insert(1) 16 | self.heap.insert(9) 17 | self.heap.insert(9) 18 | self.heap.insert(5) 19 | self.assertEqual(self.heap.storage, [10, 9, 9, 6, 1, 8, 9, 5]) 20 | 21 | def test_get_max_works(self): 22 | self.heap.insert(6) 23 | self.heap.insert(8) 24 | self.heap.insert(10) 25 | self.heap.insert(9) 26 | self.heap.insert(1) 27 | self.heap.insert(9) 28 | self.heap.insert(9) 29 | self.heap.insert(5) 30 | self.assertEqual(self.heap.get_size(), 8) 31 | self.assertEqual(self.heap.get_max(), 10) 32 | 33 | def test_get_max_after_delete(self): 34 | self.heap.insert(6) 35 | self.heap.insert(8) 36 | self.heap.insert(10) 37 | self.heap.insert(9) 38 | self.heap.insert(1) 39 | self.heap.insert(9) 40 | self.heap.insert(9) 41 | self.heap.insert(5) 42 | self.heap.delete() 43 | self.assertEqual(self.heap.get_max(), 9) 44 | self.heap.delete() 45 | self.assertEqual(self.heap.get_max(), 9) 46 | self.heap.delete() 47 | self.assertEqual(self.heap.get_max(), 9) 48 | self.heap.delete() 49 | self.assertEqual(self.heap.get_max(), 8) 50 | self.heap.delete() 51 | self.assertEqual(self.heap.get_max(), 6) 52 | 53 | def test_delete_elements_in_order(self): 54 | self.heap.insert(6) 55 | self.heap.insert(7) 56 | self.heap.insert(5) 57 | self.heap.insert(8) 58 | self.heap.insert(10) 59 | self.heap.insert(1) 60 | self.heap.insert(2) 61 | self.heap.insert(5) 62 | 63 | descending_order = [] 64 | 65 | while self.heap.get_size() > 0: 66 | descending_order.append(self.heap.delete()) 67 | 68 | self.assertEqual(descending_order, [10, 8, 7, 6, 5, 5, 2, 1]) 69 | 70 | def test_bubble_up_was_called(self): 71 | self.heap._bubble_up = MagicMock() 72 | self.heap.insert(5) 73 | self.assertTrue(self.heap._bubble_up.called) 74 | 75 | def test_sift_down_was_called(self): 76 | self.heap._sift_down = MagicMock() 77 | self.heap.insert(10) 78 | self.heap.insert(11) 79 | self.heap.delete() 80 | self.assertTrue(self.heap._sift_down.called) 81 | 82 | 83 | if __name__ == '__main__': 84 | unittest.main() 85 | -------------------------------------------------------------------------------- /Data-Structures/lru_cache/lru_cache.py: -------------------------------------------------------------------------------- 1 | class LRUCache: 2 | """ 3 | Our LRUCache class keeps track of the max number of nodes it 4 | can hold, the current number of nodes it is holding, a doubly- 5 | linked list that holds the key-value entries in the correct 6 | order, as well as a storage dict that provides fast access 7 | to every node stored in the cache. 8 | """ 9 | def __init__(self, limit=10): 10 | pass 11 | 12 | """ 13 | Retrieves the value associated with the given key. Also 14 | needs to move the key-value pair to the end of the order 15 | such that the pair is considered most-recently used. 16 | Returns the value associated with the key or None if the 17 | key-value pair doesn't exist in the cache. 18 | """ 19 | def get(self, key): 20 | pass 21 | 22 | """ 23 | Adds the given key-value pair to the cache. The newly- 24 | added pair should be considered the most-recently used 25 | entry in the cache. If the cache is already at max capacity 26 | before this entry is added, then the oldest entry in the 27 | cache needs to be removed to make room. Additionally, in the 28 | case that the key already exists in the cache, we simply 29 | want to overwrite the old value associated with the key with 30 | the newly-specified value. 31 | """ 32 | def set(self, key, value): 33 | pass 34 | -------------------------------------------------------------------------------- /Data-Structures/lru_cache/test_lru_cache.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from lru_cache import LRUCache 3 | 4 | 5 | class CacheTests(unittest.TestCase): 6 | def setUp(self): 7 | self.cache = LRUCache(3) 8 | 9 | def test_cache_overwrite_appropriately(self): 10 | self.cache.set('item1', 'a') 11 | self.cache.set('item2', 'b') 12 | self.cache.set('item3', 'c') 13 | 14 | self.cache.set('item2', 'z') 15 | 16 | self.assertEqual(self.cache.get('item1'), 'a') 17 | self.assertEqual(self.cache.get('item2'), 'z') 18 | 19 | def test_cache_insertion_and_retrieval(self): 20 | self.cache.set('item1', 'a') 21 | self.cache.set('item2', 'b') 22 | self.cache.set('item3', 'c') 23 | 24 | self.assertEqual(self.cache.get('item1'), 'a') 25 | self.cache.set('item4', 'd') 26 | 27 | self.assertEqual(self.cache.get('item1'), 'a') 28 | self.assertEqual(self.cache.get('item3'), 'c') 29 | self.assertEqual(self.cache.get('item4'), 'd') 30 | self.assertIsNone(self.cache.get('item2')) 31 | 32 | def test_cache_nonexistent_retrieval(self): 33 | self.assertIsNone(self.cache.get('nonexistent')) 34 | 35 | 36 | if __name__ == '__main__': 37 | unittest.main() 38 | -------------------------------------------------------------------------------- /Data-Structures/queue/queue.py: -------------------------------------------------------------------------------- 1 | """ 2 | A queue is a data structure whose primary purpose is to store and 3 | return elements in First In First Out order. 4 | 5 | 1. Implement the Queue class using an array as the underlying storage structure. 6 | Make sure the Queue tests pass. 7 | 2. Re-implement the Queue class, this time using the linked list implementation 8 | as the underlying storage structure. 9 | Make sure the Queue tests pass. 10 | 3. What is the difference between using an array vs. a linked list when 11 | implementing a Queue? 12 | 13 | Stretch: What if you could only use instances of your Stack class to implement the Queue? 14 | What would that look like? How many Stacks would you need? Try it! 15 | """ 16 | class Queue: 17 | def __init__(self): 18 | self.size = 0 19 | self.items = [] 20 | # self.storage = ? 21 | 22 | def __len__(self): 23 | return len(self.items) 24 | 25 | def enqueue(self, value): 26 | self.items.insert(0,value) 27 | 28 | def dequeue(self): 29 | if(len(self.items) != 0): 30 | val = self.items.pop() 31 | return val 32 | -------------------------------------------------------------------------------- /Data-Structures/queue/test_queue.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from queue import Queue 3 | 4 | class QueueTests(unittest.TestCase): 5 | def setUp(self): 6 | self.q = Queue() 7 | 8 | def test_len_returns_0_for_empty_queue(self): 9 | self.assertEqual(len(self.q), 0) 10 | 11 | def test_len_returns_correct_length_after_enqueue(self): 12 | self.assertEqual(len(self.q), 0) 13 | self.q.enqueue(2) 14 | self.assertEqual(len(self.q), 1) 15 | self.q.enqueue(4) 16 | self.assertEqual(len(self.q), 2) 17 | self.q.enqueue(6) 18 | self.q.enqueue(8) 19 | self.q.enqueue(10) 20 | self.q.enqueue(12) 21 | self.q.enqueue(14) 22 | self.q.enqueue(16) 23 | self.q.enqueue(18) 24 | self.assertEqual(len(self.q), 9) 25 | 26 | def test_empty_dequeue(self): 27 | self.assertIsNone(self.q.dequeue()) 28 | self.assertEqual(len(self.q), 0) 29 | 30 | def test_dequeue_respects_order(self): 31 | self.q.enqueue(100) 32 | self.q.enqueue(101) 33 | self.q.enqueue(105) 34 | self.assertEqual(self.q.dequeue(), 100) 35 | self.assertEqual(len(self.q), 2) 36 | self.assertEqual(self.q.dequeue(), 101) 37 | self.assertEqual(len(self.q), 1) 38 | self.assertEqual(self.q.dequeue(), 105) 39 | self.assertEqual(len(self.q), 0) 40 | self.assertIsNone(self.q.dequeue()) 41 | self.assertEqual(len(self.q), 0) 42 | 43 | if __name__ == '__main__': 44 | unittest.main() 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Data-Structures/singly_linked_list/singly_linked_list.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, value = None, next_node = None): 3 | self.value = value 4 | self.next_node = next_node 5 | 6 | def get_value(self): 7 | return self.value 8 | 9 | def get_next_node(self): 10 | return self.next_node 11 | 12 | def set_next_node(self, new_next): 13 | self.next_node = new_next 14 | 15 | 16 | 17 | class LinkedList: 18 | def __init__(self): 19 | self.head = None 20 | self.tail = None 21 | 22 | def add_to_head(self,value): 23 | new_node = Node(value) 24 | 25 | if self.head is None: 26 | self.head = new_node 27 | self.tail = new_node 28 | else: 29 | #set next_node of my new node to the head 30 | new_node.set_next_node(self.head) 31 | #update head 32 | self.head = new_node 33 | 34 | 35 | def add_to_tail(self,value): 36 | new_node = Node(value) 37 | 38 | if self.head is None: 39 | self.head = new_node 40 | self.tail = new_node 41 | else: 42 | self.tail.set_next_node(new_node) 43 | self.tail = new_node 44 | 45 | def remove_head(self): 46 | #empty list 47 | if self.head is None: 48 | return None 49 | else: 50 | return_val = self.head.get_value() 51 | #one thing 52 | if self.head == self.tail: 53 | self.head = None 54 | self.tail = None 55 | #nonempty - return a VALUE of the old head 56 | else: 57 | self.head = self.head.get_next_node() 58 | return return_val 59 | 60 | 61 | def remove_tail(self): 62 | if self.head is None: 63 | return None 64 | elif (self.head == self.tail): 65 | val = self.tail.get_value() 66 | self.tail = None 67 | self.head = None 68 | else: 69 | val = self.tail.get_value() 70 | temp = self.head 71 | while temp.get_next_node() is not self.tail: 72 | temp = temp.get_next_node() 73 | temp.set_next_node(None) 74 | self.tail = temp 75 | return val 76 | 77 | def contains(self,value): 78 | cur_node = self.head 79 | while cur_node is not None: 80 | if cur_node.get_value() == value: 81 | return True 82 | return False 83 | 84 | def get_max(self): 85 | pass -------------------------------------------------------------------------------- /Data-Structures/singly_linked_list/test_singly_linked_list.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from singly_linked_list import LinkedList 3 | 4 | class LinkedListTests(unittest.TestCase): 5 | def setUp(self): 6 | self.list = LinkedList() 7 | 8 | def test_add_to_tail(self): 9 | self.list.add_to_tail(1) 10 | self.assertEqual(self.list.tail.value, 1) 11 | self.assertEqual(self.list.head.value, 1) 12 | self.list.add_to_tail(2) 13 | self.assertEqual(self.list.tail.value, 2) 14 | self.assertEqual(self.list.head.value, 1) 15 | 16 | def test_remove_head(self): 17 | self.list.add_to_tail(10) 18 | self.list.add_to_tail(20) 19 | self.assertEqual(self.list.remove_head(), 10) 20 | self.assertEqual(self.list.remove_head(), 20) 21 | 22 | self.list.add_to_tail(10) 23 | self.assertEqual(self.list.remove_head(), 10) 24 | self.assertIsNone(self.list.head) 25 | self.assertIsNone(self.list.tail) 26 | self.assertIsNone(self.list.remove_head()) 27 | 28 | def test_remove_tail(self): 29 | self.list.add_to_tail(30) 30 | self.list.add_to_tail(40) 31 | self.assertEqual(self.list.remove_tail(), 40) 32 | self.assertEqual(self.list.remove_tail(), 30) 33 | 34 | self.list.add_to_tail(100) 35 | self.assertEqual(self.list.remove_tail(), 100) 36 | self.assertIsNone(self.list.head) 37 | self.assertIsNone(self.list.tail) 38 | self.assertIsNone(self.list.remove_tail()) 39 | 40 | if __name__ == '__main__': 41 | unittest.main() 42 | -------------------------------------------------------------------------------- /Data-Structures/stack/singly_linked_list.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, value = None, next_node = None): 3 | self.value = value 4 | self.next_node = next_node 5 | 6 | def get_value(self): 7 | return self.value 8 | 9 | def get_next_node(self): 10 | return self.next_node 11 | 12 | def set_next_node(self, new_next): 13 | self.next_node = new_next 14 | 15 | 16 | 17 | class LinkedList: 18 | def __init__(self): 19 | self.head = None 20 | self.tail = None 21 | 22 | def add_to_head(self,value): 23 | new_node = Node(value) 24 | 25 | if self.head is None: 26 | self.head = new_node 27 | self.tail = new_node 28 | else: 29 | #set next_node of my new node to the head 30 | new_node.set_next_node(self.head) 31 | #update head 32 | self.head = new_node 33 | 34 | 35 | def add_to_tail(self,value): 36 | new_node = Node(value) 37 | 38 | if self.head is None: 39 | self.head = new_node 40 | self.tail = new_node 41 | else: 42 | self.tail.set_next_node(new_node) 43 | self.tail = new_node 44 | 45 | def remove_head(self): 46 | #empty list 47 | if self.head is None: 48 | return None 49 | else: 50 | return_val = self.head.get_value() 51 | #one thing 52 | if self.head == self.tail: 53 | self.head = None 54 | self.tail = None 55 | #nonempty - return a VALUE of the old head 56 | else: 57 | self.head = self.head.get_next_node() 58 | return return_val 59 | 60 | 61 | def remove_tail(self): 62 | if(self.head is None): 63 | return None 64 | if self.head.next_node is None: 65 | self.head = None 66 | return None 67 | second_last = self.head 68 | while(second_last.next_node.next_node): 69 | second_last = second_last.next_node 70 | second_last.next_node = None 71 | return self.head.value 72 | 73 | def contains(self,value): 74 | pass 75 | 76 | def get_max(self): 77 | pass -------------------------------------------------------------------------------- /Data-Structures/stack/stack.py: -------------------------------------------------------------------------------- 1 | """ 2 | A stack is a data structure whose primary purpose is to store and 3 | return elements in Last In First Out order. 4 | 5 | 1. Implement the Stack class using an array as the underlying storage structure. 6 | Make sure the Stack tests pass. 7 | 2. Re-implement the Stack class, this time using the linked list implementation 8 | as the underlying storage structure. 9 | Make sure the Stack tests pass. 10 | 3. What is the difference between using an array vs. a linked list when 11 | implementing a Stack? 12 | """ 13 | 14 | import singly_linked_list 15 | # class Stack: 16 | 17 | # def __init__(self): 18 | # self.size = 0 19 | # self.items = [] 20 | # # self.storage = ? 21 | 22 | # def __len__(self): 23 | # return len(self.items) 24 | 25 | # def push(self, value): 26 | # self.items.append(value) 27 | 28 | # def pop(self): 29 | # if(len(self.items) != 0): 30 | # val = self.items.pop() 31 | # return val 32 | 33 | 34 | class Stack: 35 | def __init__(self): 36 | self.head = None 37 | # self.storage = ? 38 | 39 | def __len__(self): 40 | # return len(self.items) 41 | pass 42 | 43 | def push(self, value): 44 | self.items.append(value) 45 | 46 | def pop(self): 47 | if(len(self.items) != 0): 48 | val = self.items.pop() 49 | return val 50 | -------------------------------------------------------------------------------- /Data-Structures/stack/test_stack.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from stack import Stack 3 | 4 | class QueueTests(unittest.TestCase): 5 | def setUp(self): 6 | self.stack = Stack() 7 | 8 | def test_len_returns_0_for_empty_stack(self): 9 | self.assertEqual(len(self.stack), 0) 10 | 11 | def test_len_returns_correct_length_after_push(self): 12 | self.assertEqual(len(self.stack), 0) 13 | self.stack.push(2) 14 | self.assertEqual(len(self.stack), 1) 15 | self.stack.push(4) 16 | self.assertEqual(len(self.stack), 2) 17 | self.stack.push(6) 18 | self.stack.push(8) 19 | self.stack.push(10) 20 | self.stack.push(12) 21 | self.stack.push(14) 22 | self.stack.push(16) 23 | self.stack.push(18) 24 | self.assertEqual(len(self.stack), 9) 25 | 26 | def test_empty_pop(self): 27 | self.assertIsNone(self.stack.pop()) 28 | self.assertEqual(len(self.stack), 0) 29 | 30 | def test_pop_respects_order(self): 31 | self.stack.push(100) 32 | self.stack.push(101) 33 | self.stack.push(105) 34 | self.assertEqual(self.stack.pop(), 105) 35 | self.assertEqual(len(self.stack), 2) 36 | self.assertEqual(self.stack.pop(), 101) 37 | self.assertEqual(len(self.stack), 1) 38 | self.assertEqual(self.stack.pop(), 100) 39 | self.assertEqual(len(self.stack), 0) 40 | self.assertIsNone(self.stack.pop()) 41 | self.assertEqual(len(self.stack), 0) 42 | 43 | 44 | if __name__ == '__main__': 45 | unittest.main() 46 | -------------------------------------------------------------------------------- /Python Playground - Mahesh Venkitachalam.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValeriiaMur/Python-books-and-exercises/fdc2cf8399906f138e9307bb8f77082d05d81094/Python Playground - Mahesh Venkitachalam.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python-books-and-exercises -------------------------------------------------------------------------------- /adventure game/adv.py: -------------------------------------------------------------------------------- 1 | from room import Room 2 | from player import Player 3 | import sys 4 | 5 | # Declare all the rooms 6 | 7 | room = { 8 | 'outside': Room("Outside Cave Entrance", 9 | "North of you, the cave mount beckons"), 10 | 11 | 'foyer': Room("Foyer", """Dim light filters in from the south. Dusty 12 | passages run north and east."""), 13 | 14 | 'overlook': Room("Grand Overlook", """A steep cliff appears before you, falling 15 | into the darkness. Ahead to the north, a light flickers in 16 | the distance, but there is no way across the chasm."""), 17 | 18 | 'narrow': Room("Narrow Passage", """The narrow passage bends here from west 19 | to north. The smell of gold permeates the air."""), 20 | 21 | 'treasure': Room("Treasure Chamber", """You've found the long-lost treasure 22 | chamber! Sadly, it has already been completely emptied by 23 | earlier adventurers. The only exit is to the south."""), 24 | } 25 | 26 | 27 | # Link rooms together 28 | 29 | room['outside'].n_to = room['foyer'] 30 | room['foyer'].s_to = room['outside'] 31 | room['foyer'].n_to = room['overlook'] 32 | room['foyer'].e_to = room['narrow'] 33 | room['overlook'].s_to = room['foyer'] 34 | room['narrow'].w_to = room['foyer'] 35 | room['narrow'].n_to = room['treasure'] 36 | room['treasure'].s_to = room['narrow'] 37 | 38 | # 39 | # Main 40 | # 41 | 42 | # Make a new player object that is currently in the 'outside' room. 43 | 44 | player = Player(currentRoom = room["outside"]) 45 | 46 | 47 | # Write a loop that: 48 | # 49 | # * Prints the current room name 50 | # * Prints the current description (the textwrap module might be useful here). 51 | # * Waits for user input and decides what to do. 52 | # 53 | # If the user enters a cardinal direction, attempt to move to the room there. 54 | # Print an error message if the movement isn't allowed. 55 | # 56 | # If the user enters "q", quit the game. 57 | 58 | direction = "" 59 | 60 | while(direction != "q"): 61 | print(player.currentRoom.name) 62 | print(player.currentRoom.description) 63 | 64 | direction = input("""Where do you want to go bitch? 65 | w - west, 66 | s - south, 67 | n - north 68 | e - east 69 | Don't want to play my stupid game? Press q!""") 70 | 71 | if (player.currentRoom == room["outside"] and direction == "n"): 72 | player.currentRoom = room["outside"].n_to 73 | elif(player.currentRoom == room['foyer'] and direction == "s"): 74 | player.currentRoom = room["foyer"].s_to 75 | elif(player.currentRoom == room['foyer'] and direction == "n"): 76 | player.currentRoom = room["foyer"].n_to 77 | elif(player.currentRoom == room['foyer'] and direction == "e"): 78 | player.currentRoom = room["foyer"].e_to 79 | elif(player.currentRoom == room['overlook'] and direction == "s"): 80 | player.currentRoom = room["overlook"].s_to 81 | elif(player.currentRoom == room['narrow'] and direction == "w"): 82 | player.currentRoom = room["narow"].w_to 83 | elif(player.currentRoom == room['narrow'] and direction == "n"): 84 | player.currentRoom = room["narow"].n_to 85 | elif(player.currentRoom == room['treasure'] and direction == "s"): 86 | player.currentRoom = room["treasure"].s_to 87 | print("Hooray, you won and found gold!") 88 | sys.exit() 89 | else: 90 | print("Not here!") 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /adventure game/player.py: -------------------------------------------------------------------------------- 1 | # Write a class to hold player information, e.g. what room they are in 2 | # currently. 3 | 4 | from room import Room 5 | 6 | class Player: 7 | def __init__(self, currentRoom): 8 | self.currentRoom = currentRoom 9 | -------------------------------------------------------------------------------- /adventure game/room.py: -------------------------------------------------------------------------------- 1 | # Implement a class to hold room information. This should have name and 2 | # description attributes. 3 | 4 | class Room: 5 | def __init__(self, name, description): 6 | self.name = name 7 | self.description = description 8 | 9 | 10 | -------------------------------------------------------------------------------- /eating_cookies/README.md: -------------------------------------------------------------------------------- 1 | # Eating Cookies 2 | 3 | Cookie Monster can eat either 1, 2, or 3 cookies at a time. If he were given a jar of cookies with `n` cookies inside of it, how many ways could he eat all `n` cookies in the cookie jar? Implement a function `eating_cookies` that counts the number of possible ways Cookie Monster can eat all of the cookies in the jar. 4 | 5 | For example, for a jar of cookies with `n = 3` (the jar has 3 cookies inside it), there are 4 possible ways for Cookie Monster to eat all the cookies inside it: 6 | 7 | 1. He can eat 1 cookie at a time 3 times 8 | 2. He can eat 1 cookie, then 2 cookies 9 | 3. He can eat 2 cookies, then 1 cookie 10 | 4. He can eat 3 cookies all at once. 11 | 12 | Thus, `eating_cookies(3)` should return an answer of 4. 13 | 14 | Can you implement a solution that runs fast enough to pass the large input test? 15 | 16 | ## Testing 17 | 18 | For this problem, there's a test that tests your implementation with small inputs (n <= 10). There's also a separate test that tests your implementation with large inputs (n >= 50). 19 | 20 | You'll find that without implementing performance optimizations into your solution, your solution will likely hang on the large input test. 21 | 22 | To run the tests separately, run `python test_eating_cookies.py -k small` in order to run jsut the small input test. Run `python test_eating_cookies.py -k large` to execute just the large input test. If you want to run both tests, just run `python test_eating_cookies.py`. 23 | 24 | You can also test your implementation manually by executing `python eating_cookies.py [n]`. 25 | 26 | ## Hints 27 | * Since this question is asking you to generate a bunch of possible permutations, you'll probably want to use recursion for this. 28 | * Think about base cases that we would want our recursive function to stop recursing on. How many ways are there to eat 0 cookies? What about a negative number of cookies? 29 | * Once we've established some base cases, how can we recursively call our function such that we move towards one or more of these base cases? 30 | * As far as performance optimizations go, caching/memoization might be one avenue we could go down? How should we make a cache available to our recursive function through multiple recursive calls? -------------------------------------------------------------------------------- /eating_cookies/eating_cookies.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Input: an integer 3 | Returns: an integer 4 | ''' 5 | def eating_cookies(n): 6 | # Your code here 7 | if n <= 1: 8 | return 1 9 | if (n==2): 10 | return 2 11 | return eating_cookies(n-1)+eating_cookies(n-2)+eating_cookies(n-3) 12 | 13 | 14 | 15 | if __name__ == "__main__": 16 | # Use the main function here to test out your implementation 17 | num_cookies = 10 18 | 19 | print(f"There are {eating_cookies(num_cookies)} ways for Cookie Monster to each {num_cookies} cookies") 20 | -------------------------------------------------------------------------------- /eating_cookies/test_eating_cookies.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from eating_cookies import eating_cookies 3 | 4 | class Test(unittest.TestCase): 5 | 6 | def test_eating_cookies_small_n(self): 7 | self.assertEqual(eating_cookies(0), 1) 8 | self.assertEqual(eating_cookies(1), 1) 9 | self.assertEqual(eating_cookies(2), 2) 10 | self.assertEqual(eating_cookies(5), 13) 11 | self.assertEqual(eating_cookies(10), 274) 12 | 13 | def test_eating_cookies_large_n(self): 14 | self.assertEqual(eating_cookies(50, [0 for i in range(51)]), 10562230626642) 15 | self.assertEqual(eating_cookies(100, [0 for i in range(101)]), 180396380815100901214157639) 16 | self.assertEqual(eating_cookies(500, [0 for i in range(501)]), 1306186569702186634983475450062372018715120191391192207156664343051610913971927959744519676992404852130396504615663042713312314219527) 17 | 18 | 19 | if __name__ == '__main__': 20 | unittest.main() -------------------------------------------------------------------------------- /examples games/guessing_game.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | def guessing_game(): 4 | print("Guess the number!") 5 | 6 | secret_number = random.randrange(101) 7 | 8 | while True: 9 | guess = input("Input your guess: ") 10 | 11 | try: 12 | guess = int(guess) 13 | except ValueError: 14 | print("Please enter an integer.") 15 | continue 16 | 17 | print(f"You guessed: {guess}") 18 | 19 | if guess == secret_number: 20 | print("You win!") 21 | break 22 | elif guess < secret_number: 23 | print("Too small!") 24 | else: 25 | print("Too big!") 26 | 27 | if __name__ == '__main__': 28 | guessing_game() -------------------------------------------------------------------------------- /examples games/history.txt: -------------------------------------------------------------------------------- 1 | 3,3,0 -------------------------------------------------------------------------------- /examples games/rock_paper_scissors.py: -------------------------------------------------------------------------------- 1 | #import module we need 2 | import random 3 | 4 | #file i/o functions for historical results 5 | def load_results(): 6 | text_file = open("history.txt", "r") 7 | history = text_file.read().split(",") 8 | text_file.close() 9 | return history 10 | 11 | def save_results( w, t, l): 12 | text_file = open("history.txt", "w") 13 | text_file.write( str(w) + "," + str(t) + "," + str(l)) 14 | text_file.close() 15 | 16 | #welcome message 17 | results = load_results() 18 | wins = int(results[0]) 19 | ties = int( results[1]) 20 | losses = int(results[2]) 21 | print("Welcome to Rock, Paper, Scissors!") 22 | print("Wins: %s, Ties: %s, Losses: %s" % (wins, ties, losses)) 23 | print("Please choose to continue...") 24 | 25 | 26 | #initialize user, computer choices 27 | computer = random.randint(1,3) 28 | user = int(input("[1] Rock [2] Paper [3] Scissors [9] Quit\n")) 29 | 30 | #gamplay loop 31 | while not user == 9: 32 | #user chooses ROCK 33 | if user == 1: 34 | if computer == 1: 35 | print("Computer chose rock...tie!") 36 | ties += 1 37 | elif computer == 2: 38 | print("Computer chose paper...computer wins :(") 39 | losses += 1 40 | else: 41 | print("Computer chose scissors...you wins :)") 42 | wins += 1 43 | 44 | #user chooses PAPER 45 | elif user == 2: 46 | if computer == 1: 47 | print("Computer chose rock...you win :)") 48 | wins += 1 49 | elif computer == 2: 50 | print("Computer chose paper...tie!") 51 | ties += 1 52 | else: 53 | print("Computer chose scissors...computer wins :(") 54 | losses += 1 55 | 56 | #user chooses SCISSORS 57 | elif user == 3: 58 | if computer == 1: 59 | print("Computer chose rock...computer wins :(") 60 | losses += 1 61 | elif computer == 2: 62 | print("Computer chose paper...you win :)") 63 | wins += 1 64 | else: 65 | print("Computer chose scissors...tie!") 66 | ties += 1 67 | else: 68 | print("Invalid selection. Please try again.") 69 | #print updated stats 70 | print("Wins: %s, Ties: %s, Losses: %s" % (wins, ties, losses)) 71 | 72 | #prompt user to make another selection 73 | print("Please choose to continue...") 74 | #initialize user, computer choices 75 | computer = random.randint(1,3) 76 | user = int(input("[1] Rock [2] Paper [3] Scissors [9] Quit\n")) 77 | 78 | # #game over, save results 79 | save_results(wins, ties, losses) -------------------------------------------------------------------------------- /iterative_sorting/README.md: -------------------------------------------------------------------------------- 1 | # Iterative Sorting Algorithms 2 | 3 | ## Bubble Sort 4 | 5 | In **Bubble Sort**, we make a series of swaps between adjacent elements, gradually moving larger elements towards the end of the array (or _bubbling_ larger elements up). 6 | 7 | ### Algorithm 8 | 9 | 1. Loop through your array 10 | - Compare each element to its neighbor 11 | - If elements in wrong position (relative to each other, swap them) 12 | 2. If no swaps performed, stop. Else, go back to the element at index 0 and repeat step 1. 13 | 14 | ### Real-World Applications 15 | 16 | ***Bubble Sort*** is not ideal for many real-world applications. If a small element that _should_ be at the beginning of our array is originally located near the end, it will take a long time to move it into its correct position. 17 | 18 | However, it should be noted that if you perform **Bubble Sort** on an array that's already sorted, it will only require a single pass through the array, making its best-case performance linear. It's also very simple to implement. 19 | 20 | ## Selection Sort 21 | 22 | ***Selection Sort*** is an algorithm that many of you have probably used before when sorting things in your everyday lives. Imagine that you have several books you want to arrange on a shelf from shortest to tallest. You start off by looking for the shortest book, and when you find it, put it on the far left side of the shelf. Then, you look for the second shortest book and insert it directly to the right of the first book. You repeat this process, selecting the next shortest book and moving it next to the most recently placed book, until you have moved all books into the correct place. This is ***Selection Sort***. 23 | 24 | An example of this algorithm being applied to an array with 10 numerical elements can be seen in the video below. 25 | 26 | [(VIDEO) Select-sort with Gypsy folk dance](https://www.youtube.com/watch?v=Ns4TPTC8whw) 27 | 28 | [![(VIDEO) Select-sort with Gypsy folk dance](https://i.ytimg.com/vi/Ns4TPTC8whw/hqdefault.jpg)](https://www.youtube.com/watch?v=Ns4TPTC8whw) 29 | 30 | ### Algorithm 31 | 32 | 1. Start with current index = 0 33 | 34 | 2. For all indices EXCEPT the last index: 35 | 36 | a. Loop through elements on right-hand-side 37 | of current index and find the smallest element 38 | 39 | b. Swap the element at current index with the 40 | smallest element found in above loop 41 | 42 | ### Real-World Applications 43 | 44 | While ***Selection Sort*** is one of the easier sorting algorithms to understand and implement, it has one major drawback - its efficiency. 45 | 46 | Recall that the runtime complexity of an algorithm, often expressed using *Big O notation*, tells us how the amount of operations our algorithm requires will grow as the size of our input grows. ***Selection Sort*** has a runtime of O(n²), making it impractical to use with many large, real-world data sets. 47 | -------------------------------------------------------------------------------- /iterative_sorting/iterative_sorting.py: -------------------------------------------------------------------------------- 1 | # TO-DO: Complete the selection_sort() function below 2 | def selection_sort(arr): 3 | # loop through n-1 elements 4 | for i in range(0, len(arr) - 1): 5 | # cur_index = i 6 | smallest_index = i 7 | # TO-DO: find next smallest element 8 | # (hint, can do in 3 loc) 9 | # Your code here 10 | for j in range(i+1, len(arr)): 11 | if arr[smallest_index] > arr[j]: 12 | smallest_index = j 13 | 14 | 15 | # TO-DO: swap 16 | # Your code here 17 | arr[i], arr[smallest_index] = arr[smallest_index],arr[i] 18 | 19 | return arr 20 | 21 | 22 | # TO-DO: implement the Bubble Sort function below 23 | def bubble_sort(arr): 24 | # Your code here 25 | n = len(arr) 26 | 27 | for i in range(n - 1): 28 | for j in range(n-i-1): 29 | if arr[j] > arr[j+1]: 30 | arr[j], arr[j+1] = arr[j+1],arr[j] 31 | 32 | return arr 33 | 34 | ''' 35 | STRETCH: implement the Counting Sort function below 36 | 37 | Counting sort is a sorting algorithm that works on a set of data where 38 | we specifically know the maximum value that can exist in that set of 39 | data. The idea behind this algorithm then is that we can create "buckets" 40 | from 0 up to the max value. This is most easily done by initializing an 41 | array of 0s whose length is the max value + 1 (why do we need this "+ 1"?). 42 | 43 | Each buckets[i] then is responsible for keeping track of how many times 44 | we've seen `i` in the input set of data as we iterate through it. 45 | Once we know exactly how many times each piece of data in the input set 46 | showed up, we can construct a sorted set of the input data from the 47 | buckets. 48 | 49 | What is the time and space complexity of the counting sort algorithm? 50 | ''' 51 | def counting_sort(arr, maximum=None): 52 | # Your code here 53 | 54 | 55 | return arr 56 | -------------------------------------------------------------------------------- /iterative_sorting/test_iterative.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import random 3 | from iterative_sorting import * 4 | 5 | class IterativeSortingTest(unittest.TestCase): 6 | def test_selection_sort(self): 7 | arr1 = [1, 5, 8, 4, 2, 9, 6, 0, 3, 7] 8 | arr2 = [] 9 | arr3 = [0, 1, 2, 3, 4, 5] 10 | arr4 = random.sample(range(200), 50) 11 | 12 | self.assertEqual(selection_sort(arr1), [0,1,2,3,4,5,6,7,8,9]) 13 | self.assertEqual(selection_sort(arr2), []) 14 | self.assertEqual(selection_sort(arr3), [0,1,2,3,4,5]) 15 | self.assertEqual(selection_sort(arr4), sorted(arr4)) 16 | 17 | def test_bubble_sort(self): 18 | arr1 = [1, 5, 8, 4, 2, 9, 6, 0, 3, 7] 19 | arr2 = [] 20 | arr3 = [0, 1, 2, 3, 4, 5] 21 | arr4 = random.sample(range(200), 50) 22 | 23 | self.assertEqual(bubble_sort(arr1), [0,1,2,3,4,5,6,7,8,9]) 24 | self.assertEqual(bubble_sort(arr2), []) 25 | self.assertEqual(bubble_sort(arr3), [0,1,2,3,4,5]) 26 | self.assertEqual(bubble_sort(arr4), sorted(arr4)) 27 | 28 | # Uncomment this test to test your count_sort implementation 29 | # def test_counting_sort(self): 30 | # arr1 = [1, 5, 8, 4, 2, 9, 6, 0, 3, 7] 31 | # arr2 = [] 32 | # arr3 = [1, 5, -2, 4, 3] 33 | # arr4 = random.sample(range(200), 50) 34 | 35 | # self.assertEqual(counting_sort(arr1), [0,1,2,3,4,5,6,7,8,9]) 36 | # self.assertEqual(counting_sort(arr2), []) 37 | # self.assertEqual(counting_sort(arr3), "Error, negative numbers not allowed in Count Sort") 38 | # self.assertEqual(counting_sort(arr4), sorted(arr4)) 39 | 40 | 41 | if __name__ == '__main__': 42 | unittest.main() 43 | -------------------------------------------------------------------------------- /names/names.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | start_time = time.time() 4 | 5 | f = open('names_1.txt', 'r') 6 | names_1 = f.read().split("\n") # List containing 10000 names 7 | f.close() 8 | 9 | f = open('names_2.txt', 'r') 10 | names_2 = f.read().split("\n") # List containing 10000 names 11 | f.close() 12 | 13 | duplicates = [] 14 | names_dict ={} # Return the list of duplicates in this data structure 15 | 16 | # Replace the nested for loops below with your improvements 17 | for name_1 in names_1: 18 | names_dict[name_1] = True 19 | for name_2 in names_2: 20 | if name_2 in names_dict: 21 | duplicates.append(name_2) 22 | 23 | end_time = time.time() 24 | print (f"{len(duplicates)} duplicates:\n\n{', '.join(duplicates)}\n\n") 25 | print (f"runtime: {end_time - start_time} seconds") 26 | 27 | # ---------- Stretch Goal ----------- 28 | # Python has built-in tools that allow for a very efficient approach to this problem 29 | # What's the best time you can accomplish? Thare are no restrictions on techniques or data 30 | # structures, but you may not import any additional libraries that you did not write yourself. 31 | -------------------------------------------------------------------------------- /python-crash-course.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValeriiaMur/Python-books-and-exercises/fdc2cf8399906f138e9307bb8f77082d05d81094/python-crash-course.pdf -------------------------------------------------------------------------------- /reverse/reverse.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, value=None, next_node=None): 3 | self.value = value 4 | self.next_node = next_node 5 | 6 | def get_value(self): 7 | return self.value 8 | 9 | def get_next(self): 10 | return self.next_node 11 | 12 | def set_next(self, new_next): 13 | self.next_node = new_next 14 | 15 | class LinkedList: 16 | def __init__(self): 17 | self.head = None 18 | 19 | def add_to_head(self, value): 20 | node = Node(value) 21 | 22 | if self.head is not None: 23 | node.set_next(self.head) 24 | 25 | self.head = node 26 | 27 | def contains(self, value): 28 | if not self.head: 29 | return False 30 | 31 | current = self.head 32 | 33 | while current: 34 | if current.get_value() == value: 35 | return True 36 | 37 | current = current.get_next() 38 | 39 | return False 40 | 41 | def reverse_list(self, node, prev): 42 | if self.head is None: 43 | return 44 | current_node = self.head 45 | while current_node.get_next() is not None: 46 | self.add_to_head(current_node.get_next()) 47 | current_node = current_node.get_next() 48 | -------------------------------------------------------------------------------- /reverse/test_reverse.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from reverse import LinkedList 3 | 4 | class LinkedListTests(unittest.TestCase): 5 | def setUp(self): 6 | self.list = LinkedList() 7 | 8 | def test_add_to_head(self): 9 | self.list.add_to_head(1) 10 | self.assertEqual(self.list.head.value, 1) 11 | self.list.add_to_head(2) 12 | self.assertEqual(self.list.head.value, 2) 13 | 14 | def test_contains(self): 15 | self.list.add_to_head(1) 16 | self.list.add_to_head(2) 17 | self.list.add_to_head(10) 18 | self.assertTrue(self.list.contains(2)) 19 | self.assertTrue(self.list.contains(10)) 20 | self.assertFalse(self.list.contains(1000)) 21 | 22 | def test_empty_reverse(self): 23 | self.list.reverse_list(self.list.head, None) 24 | self.assertEqual(self.list.head, None) 25 | 26 | def test_single_reverse(self): 27 | self.list.add_to_head(1) 28 | self.list.reverse_list(self.list.head, None) 29 | self.assertEqual(self.list.head.value, 1) 30 | 31 | def test_longer_reverse(self): 32 | self.list.add_to_head(1) 33 | self.list.add_to_head(2) 34 | self.list.add_to_head(3) 35 | self.list.add_to_head(4) 36 | self.list.add_to_head(5) 37 | self.assertEqual(self.list.head.value, 5) 38 | self.list.reverse_list(self.list.head, None) 39 | self.assertEqual(self.list.head.value, 1) 40 | self.assertEqual(self.list.head.get_next().value, 2) 41 | self.assertEqual(self.list.head.get_next().get_next().value, 3) 42 | 43 | if __name__ == '__main__': 44 | unittest.main() -------------------------------------------------------------------------------- /ring_buffer/ring_buffer.py: -------------------------------------------------------------------------------- 1 | class RingBuffer: 2 | def __init__(self, capacity): 3 | self.capacity = capacity 4 | self.current = 0 5 | self.storage = [None]*capacity 6 | 7 | def append(self, item): 8 | if self.current < len(self.storage): 9 | self.storage[self.current] = item 10 | self.current += 1 11 | return self.storage 12 | else: 13 | self.current = 0 14 | return self.append(item) 15 | 16 | def get(self): 17 | res = [] 18 | for i in range(len(self.storage)): 19 | if self.storage[i] is not None: 20 | res.append(self.storage[i]) 21 | return res 22 | 23 | # buffer = RingBuffer(3) 24 | 25 | # buffer.get() # should return [] 26 | 27 | # buffer.append('a') 28 | # buffer.append('b') 29 | # buffer.append('c') 30 | 31 | # print(buffer.get() ) # should return ['a', 'b', 'c'] 32 | 33 | # # 'd' overwrites the oldest value in the ring buffer, which is 'a' 34 | # buffer.append('d') 35 | 36 | # print(buffer.get()) # should return ['d', 'b', 'c'] 37 | 38 | # buffer.append('e') 39 | # buffer.append('f') 40 | 41 | # print(buffer.get()) # should return ['d', 'e', 'f'] -------------------------------------------------------------------------------- /ring_buffer/test_ring_buffer.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from ring_buffer import RingBuffer 3 | 4 | class RingBufferTests(unittest.TestCase): 5 | def setUp(self): 6 | self.capacity = 5 7 | self.buffer = RingBuffer(self.capacity) 8 | 9 | def test_new_buffer_has_appropriate_capacity(self): 10 | self.assertEqual(self.buffer.capacity, self.capacity) 11 | 12 | def test_adding_one_element_to_buffer(self): 13 | self.buffer.append('a') 14 | self.assertEqual(self.buffer.get(), ['a']) 15 | 16 | def test_filling_buffer_to_capacity(self): 17 | self.buffer.append('a') 18 | self.buffer.append('b') 19 | self.buffer.append('c') 20 | self.buffer.append('d') 21 | self.buffer.append('e') 22 | self.assertEqual(self.buffer.get(), ['a', 'b', 'c', 'd', 'e']) 23 | 24 | def test_adding_one_element_to_full_buffer(self): 25 | self.buffer.append('a') 26 | self.buffer.append('b') 27 | self.buffer.append('c') 28 | self.buffer.append('d') 29 | self.buffer.append('e') 30 | self.buffer.append('f') 31 | self.assertEqual(self.buffer.get(), ['f', 'b', 'c', 'd', 'e']) 32 | 33 | def test_adding_many_elements_to_full_buffer(self): 34 | self.buffer.append('a') 35 | self.buffer.append('b') 36 | self.buffer.append('c') 37 | self.buffer.append('d') 38 | self.buffer.append('e') 39 | self.buffer.append('f') 40 | self.buffer.append('g') 41 | self.buffer.append('h') 42 | self.buffer.append('i') 43 | self.assertEqual(self.buffer.get(), ['f', 'g', 'h', 'i', 'e']) 44 | 45 | def test_adding_50_elements_to_buffer(self): 46 | for i in range(50): 47 | self.buffer.append(i) 48 | 49 | self.assertEqual(self.buffer.get(), [45, 46, 47, 48, 49]) 50 | 51 | if __name__ == '__main__': 52 | unittest.main() -------------------------------------------------------------------------------- /searching/README.md: -------------------------------------------------------------------------------- 1 | # Part 1: Why is it So Important to Sort Data? 2 | 3 | ## We're Always Searching 4 | Users do not have patience for slow apps. And rightfully so! While a a big reason why the applications we use now-a-days are so fast is due to the improvements made in hardware over the last few decades, the software developer still has an important role to play in keeping everything moving quickly. 5 | 6 | As we write our applications, we should always be mindful of what operations are being done frequently, since optimizing these will have the biggest impact on the efficiency of our overall application. And regardless of *what* type of app you are creating, it is likely that one of the operations you will be relying on is ***searching***. We search for songs to add to a playlist, videos to watch, people we need to talk to and so much more. Because of this, it is essential that we optimize our searches. 7 | 8 | ## Linear vs. Binary Search 9 | There are two common searching algorithms that developers are often introduced to when they are writing some of their first apps: **linear search** and **binary search**. Let's walk through the differences between them. 10 | 11 | ### Linear (Sequential) Search 12 | 13 | Sometimes referred to as sequential search, this algorithm is fairly straightforward. Given a set of data, traverse the dataset one item at a time until either you find the item you are looking for OR check every item in the set and verify the item you are looking for is not there. 14 | 15 | ### Binary Search 16 | 17 | The process of performing a binary search has a couple of extra steps. First, there is a *precondition* that the set of data you are searching is ***already sorted*** (alphabetically, numerically, etc). Then, the steps to search are: 18 | 19 | 1. Compare the item in the middle of the data set to the item we are searching for. 20 | - If it is the same, stop. We found it and are done! 21 | - Else, if the item we are searching for is LESS than the item in the middle: 22 | - Eliminate the RHS of list. Repeat step 1 with only the LHS of list. 23 | - Else, the item we are searching for is GREATER than the item in the middle: 24 | - Eliminate the LHS of list. Repeat step 1 with only the RHS of the list. 25 | 26 | 27 | A visualization comparing these two algorithms is shown below. 28 | ![binary v sequential](https://www.mathwarehouse.com/programming/images/binary-vs-linear-search/binary-and-linear-search-animations.gif "Binary v Sequential Search") 29 | 30 | ### Your Task 31 | - Complete all of the functions in the `searching.py` file. 32 | 33 | ### Runtimes 34 | 35 | These two searching strategies have very different runtimes. 36 | 37 | **Linear Search:** O(n) 38 | **Binary Search:** O(log(n)) 39 | 40 | Looking at the above runtimes, it is clear that we should be using binary search over linear search. 41 | ***However, we cannot perform binary search if our data isn't ALREADY SORTED!*** 42 | 43 | While the justification for *WHY* we want to sort our data is pretty clear, a harder question to answer is *HOW* do we want to sort our data. Over the next few days, we will explore several different sorting algorithms, examining the pros and cons of each. 44 | 45 | [Just for fun...(VIDEO) 15 Sorting Algorithms in 6 Minutes ![alt text](https://i.ytimg.com/vi/kPRA0W1kECg/maxresdefault.jpg)](https://www.youtube.com/watch?v=kPRA0W1kECg) -------------------------------------------------------------------------------- /searching/searching.py: -------------------------------------------------------------------------------- 1 | def linear_search(arr, target): 2 | # Your code here 3 | for i in range(len(arr)): 4 | if(arr[i] == target): 5 | return i 6 | 7 | return -1 # not found 8 | 9 | 10 | # Write an iterative implementation of Binary Search 11 | def binary_search(arr, target): 12 | 13 | # Your code here 14 | low = 0 15 | high=len(arr) - 1 16 | mid = 0 17 | 18 | while low <= high: 19 | mid = (low+high)//2 20 | 21 | if(arr[mid] < target): 22 | low = mid+1 23 | elif(arr[mid]>target): 24 | high=mid-1 25 | else: 26 | return mid 27 | return -1 # not found 28 | -------------------------------------------------------------------------------- /searching/test_searching.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from searching import * 3 | 4 | 5 | class SearchingTests(unittest.TestCase): 6 | def test_linear_search(self): 7 | arr1 = [-2, 7, 3, -9, 5, 1, 0, 4, -6] 8 | arr2 = [] 9 | 10 | self.assertEqual(linear_search(arr1, 6), -1) 11 | self.assertEqual(linear_search(arr1, -6), 8) 12 | self.assertEqual(linear_search(arr1, 0), 6) 13 | self.assertEqual(linear_search(arr2, 3), -1) 14 | 15 | def test_binary_search(self): 16 | arr1 = [-9, -8, -6, -4, -3, -2, 0, 1, 2, 3, 5, 7, 8, 9] 17 | arr2 = [] 18 | 19 | self.assertEqual(binary_search(arr1, -8), 1) 20 | self.assertEqual(binary_search(arr1, 0), 6) 21 | self.assertEqual(binary_search(arr2, 6), -1) 22 | self.assertEqual(binary_search(arr2, 0), -1) 23 | 24 | 25 | if __name__ == '__main__': 26 | unittest.main() 27 | -------------------------------------------------------------------------------- /small bits/00_hello.py: -------------------------------------------------------------------------------- 1 | # Print "Hello, world!" to your terminal 2 | 3 | print("Hello, world!"); -------------------------------------------------------------------------------- /small bits/01_bignum.py: -------------------------------------------------------------------------------- 1 | # Print out 2 to the 65536 power 2 | # (try doing the same thing in the JS console and see what it outputs) 3 | 4 | # YOUR CODE HERE 5 | print(pow(2, 65)) -------------------------------------------------------------------------------- /small bits/02_datatypes.py: -------------------------------------------------------------------------------- 1 | """ 2 | Python is a strongly-typed language under the hood, which means 3 | that the types of values matter, especially when we're trying 4 | to perform operations on them. 5 | 6 | Note that if you try running the following code without making any 7 | changes, you'll get a TypeError saying you can't perform an operation 8 | on a string and an integer. 9 | """ 10 | 11 | x = 5 12 | y = "7" 13 | 14 | # Write a print statement that combines x + y into the integer value 12 15 | print(x + int(7)) 16 | 17 | # YOUR CODE HERE 18 | 19 | 20 | # Write a print statement that combines x + y into the string value 57 21 | print(str(x) + y) 22 | 23 | # YOUR CODE HERE -------------------------------------------------------------------------------- /small bits/03_modules.py: -------------------------------------------------------------------------------- 1 | """ 2 | In this exercise, you'll be playing around with the sys module, 3 | which allows you to access many system specific variables and 4 | methods, and the os module, which gives you access to lower- 5 | level operating system functionality. 6 | """ 7 | 8 | import sys 9 | # See docs for the sys module: https://docs.python.org/3.7/library/sys.html 10 | 11 | # Print out the command line arguments in sys.argv, one per line: 12 | # YOUR CODE HERE 13 | for arg in sys.argv: 14 | print (arg) 15 | 16 | # Print out the OS platform you're using: 17 | # YOUR CODE HERE 18 | 19 | print(sys.platform) 20 | 21 | # Print out the version of Python you're using: 22 | # YOUR CODE HERE 23 | 24 | print(sys.version) 25 | 26 | 27 | import os 28 | # See the docs for the OS module: https://docs.python.org/3.7/library/os.html 29 | 30 | # Print the current process ID 31 | # YOUR CODE HERE 32 | print(os.getegid()) 33 | 34 | # Print the current working directory (cwd): 35 | # YOUR CODE HERE 36 | 37 | print(os.getcwd()) 38 | 39 | # Print out your machine's login name 40 | # YOUR CODE HERE 41 | print(os.getlogin()) 42 | -------------------------------------------------------------------------------- /small bits/04_printing.py: -------------------------------------------------------------------------------- 1 | """ 2 | Python provides a number of ways to perform printing. Research 3 | how to print using the printf operator, the `format` string 4 | method, and by using f-strings. 5 | """ 6 | 7 | x = 10 8 | y = 2.24552 9 | z = "I like turtles!" 10 | 11 | # Using the printf operator (%), print the following feeding in the values of x, 12 | # y, and z: 13 | # x is 10, y is 2.25, z is "I like turtles!" 14 | print("x is %d, y is %f, z is %s" % (x,y,z)) 15 | 16 | # Use the 'format' string method to print the same thing 17 | 18 | print("x is {}, y is {}, z is {}".format(x,y,z)) 19 | 20 | # Finally, print the same thing using an f-string 21 | print(f"x is {x}, y is {y}, z is {z}") -------------------------------------------------------------------------------- /small bits/05_lists.py: -------------------------------------------------------------------------------- 1 | # For the exercise, look up the methods and functions that are available for use 2 | # with Python lists. 3 | 4 | x = [1, 2, 3] 5 | y = [8, 9, 10] 6 | 7 | # For the following, DO NOT USE AN ASSIGNMENT (=). 8 | 9 | # Change x so that it is [1, 2, 3, 4] 10 | # YOUR CODE HERE 11 | x.append(4) 12 | print(x) 13 | 14 | # Using y, change x so that it is [1, 2, 3, 4, 8, 9, 10] 15 | # YOUR CODE HERE 16 | x = x + y 17 | print(x) 18 | 19 | # Change x so that it is [1, 2, 3, 4, 9, 10] 20 | # YOUR CODE HERE 21 | x.remove(8) 22 | print(x) 23 | 24 | # Change x so that it is [1, 2, 3, 4, 9, 99, 10] 25 | # YOUR CODE HERE 26 | x.insert(5, 99) 27 | print(x) 28 | 29 | # Print the length of list x 30 | # YOUR CODE HERE 31 | print(len(x)) 32 | 33 | # Print all the values in x multiplied by 1000 34 | # YOUR CODE HERE 35 | for num in x: 36 | print (num * 1000) -------------------------------------------------------------------------------- /small bits/06_tuples.py: -------------------------------------------------------------------------------- 1 | """ 2 | Python tuples are sort of like lists, except they're immutable and 3 | are usually used to hold heterogenous data, as opposed to lists 4 | which are typically used to hold homogenous data. Tuples use 5 | parens instead of square brackets. 6 | 7 | More specifically, tuples are faster than lists. If you're looking 8 | to just define a constant set of values and that set of values 9 | never needs to be mutated, use a tuple instead of a list. 10 | 11 | Additionally, your code will be safer if you opt to "write-protect" 12 | data that does not need to be changed. Tuples enforce immutability 13 | automatically. 14 | """ 15 | 16 | # Example: 17 | 18 | import math 19 | 20 | def dist(a, b): 21 | """Compute the distance between two x,y points.""" 22 | x0, y0 = a # Destructuring assignment 23 | x1, y1 = b 24 | 25 | return math.sqrt((x1 - x0)**2 + (y1 - y0)**2) 26 | 27 | a = (2, 7) # <-- x,y coordinates stored in tuples 28 | b = (-14, 72) 29 | 30 | # Prints "Distance is 66.94" 31 | print("Distance is: {:.2f}".format(dist(a, b))) 32 | 33 | 34 | 35 | # Write a function `print_tuple` that prints all the values in a tuple 36 | def print_tuple(tuple): 37 | for num in tuple: 38 | print(num) 39 | 40 | # YOUR CODE HERE 41 | 42 | t = (1, 2, 5, 7, 99) 43 | print_tuple(t) # Prints 1 2 5 7 99, one per line 44 | 45 | # Declare a tuple of 1 element then print it 46 | u = (1,) # What needs to be added to make this work? 47 | print_tuple(u) 48 | -------------------------------------------------------------------------------- /small bits/07_slices.py: -------------------------------------------------------------------------------- 1 | """ 2 | Python exposes a terse and intuitive syntax for performing 3 | slicing on lists and strings. This makes it easy to reference 4 | only a portion of a list or string. 5 | 6 | This Stack Overflow answer provides a brief but thorough 7 | overview: https://stackoverflow.com/a/509295 8 | 9 | Use Python's slice syntax to achieve the following: 10 | """ 11 | 12 | a = [2, 4, 1, 7, 9, 6] 13 | 14 | # Output the second element: 4: 15 | print(a[2:3]) 16 | 17 | # Output the second-to-last element: 9 18 | print(a[-2:-1]) 19 | 20 | # Output the last three elements in the array: [7, 9, 6] 21 | print(a[-3:]) 22 | 23 | # Output the two middle elements in the array: [1, 7] 24 | print(a[2:4]) 25 | 26 | # Output every element except the first one: [4, 1, 7, 9, 6] 27 | print(a[1:]) 28 | 29 | # Output every element except the last one: [2, 4, 1, 7, 9] 30 | print(a[:-1]) 31 | 32 | # For string s... 33 | 34 | s = "Hello, world!" 35 | 36 | # Output just the 8th-12th characters: "world" 37 | print(s[7:12]) -------------------------------------------------------------------------------- /small bits/08_comprehensions.py: -------------------------------------------------------------------------------- 1 | """ 2 | List comprehensions are one cool and unique feature of Python. 3 | They essentially act as a terse and concise way of initializing 4 | and populating a list given some expression that specifies how 5 | the list should be populated. 6 | 7 | Take a look at https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions 8 | for more info regarding list comprehensions. 9 | """ 10 | 11 | # Write a list comprehension to produce the array [1, 2, 3, 4, 5] 12 | 13 | y = [x for x in range(1,6)] 14 | 15 | 16 | print (y) 17 | 18 | # Write a list comprehension to produce the cubes of the numbers 0-9: 19 | # [0, 1, 8, 27, 64, 125, 216, 343, 512, 729] 20 | 21 | y = [pow(x,3) for x in range(10)] 22 | 23 | print(y) 24 | 25 | # Write a list comprehension to produce the uppercase version of all the 26 | # elements in array a. Hint: "foo".upper() is "FOO". 27 | 28 | a = ["foo", "bar", "baz"] 29 | 30 | y = [x.upper() for x in a] 31 | 32 | print(y) 33 | 34 | # Use a list comprehension to create a list containing only the _even_ elements 35 | # the user entered into list x. 36 | 37 | x = input("Enter comma-separated numbers: ").split(',') 38 | 39 | # What do you need between the square brackets to make it work? 40 | y = [i for i in x if int(i)%2 == 0] 41 | 42 | print(y) -------------------------------------------------------------------------------- /small bits/09_dictionaries.py: -------------------------------------------------------------------------------- 1 | """ 2 | Dictionaries are Python's implementation of associative arrays. 3 | There's not much different with Python's version compared to what 4 | you'll find in other languages (though you can also initialize and 5 | populate dictionaries using comprehensions just like you can with 6 | lists!). 7 | 8 | The docs can be found here: 9 | https://docs.python.org/3/tutorial/datastructures.html#dictionaries 10 | 11 | For this exercise, you have a list of dictionaries. Each dictionary 12 | has the following keys: 13 | - lat: a signed integer representing a latitude value 14 | - lon: a signed integer representing a longitude value 15 | - name: a name string for this location 16 | """ 17 | 18 | waypoints = [ 19 | { 20 | "lat": 43, 21 | "lon": -121, 22 | "name": "a place" 23 | }, 24 | { 25 | "lat": 41, 26 | "lon": -123, 27 | "name": "another place" 28 | }, 29 | { 30 | "lat": 43, 31 | "lon": -122, 32 | "name": "a third place" 33 | } 34 | ] 35 | 36 | # Add a new waypoint to the list 37 | # YOUR CODE HERE 38 | 39 | waypoints.append({ 40 | "lat": 44, 41 | "lon": -12442, 42 | "name": "a forth place" 43 | }) 44 | 45 | 46 | 47 | # Modify the dictionary with name "a place" such that its longitude 48 | # value is -130 and change its name to "not a real place" 49 | # Note: It's okay to access the dictionary using bracket notation on the 50 | # waypoints list. 51 | 52 | waypoints[0]["lon"] = -130 53 | waypoints[0]["name"] = "Not a real place" 54 | 55 | print(waypoints) 56 | 57 | 58 | # YOUR CODE HERE 59 | 60 | # Write a loop that prints out all the field values for all the waypoints 61 | # YOUR CODE HERE 62 | 63 | for item in waypoints: 64 | for key in item: 65 | print(key,"->",item[key]) -------------------------------------------------------------------------------- /small bits/10_functions.py: -------------------------------------------------------------------------------- 1 | # Write a function is_even that will return true if the passed-in number is even. 2 | 3 | # YOUR CODE HERE 4 | 5 | # Read a number from the keyboard 6 | num = input("Enter a number: ") 7 | num = int(num) 8 | 9 | # Print out "Even!" if the number is even. Otherwise print "Odd" 10 | 11 | def is_even(num): 12 | if(num %2 == 0): 13 | print("Even!") 14 | else: 15 | print("Odd") 16 | 17 | is_even(num) 18 | 19 | # YOUR CODE HERE 20 | 21 | -------------------------------------------------------------------------------- /small bits/11_args.py: -------------------------------------------------------------------------------- 1 | # Experiment with positional arguments, arbitrary arguments, and keyword 2 | # arguments. 3 | 4 | # Write a function f1 that takes two integer positional arguments and returns 5 | # the sum. This is what you'd consider to be a regular, normal function. 6 | 7 | # YOUR CODE HERE 8 | 9 | def f1(num1, num2): 10 | return num1+ num2 11 | 12 | # print(f1(1, 2)) 13 | 14 | # Write a function f2 that takes any number of integer arguments and returns the 15 | # sum. 16 | # Note: Google for "python arbitrary arguments" and look for "*args" 17 | 18 | # YOUR CODE HERE 19 | 20 | def f2(*args): 21 | return sum(args) 22 | 23 | # print(f2(1)) # Should print 1 24 | # print(f2(1, 3)) # Should print 4 25 | # print(f2(1, 4, -12)) # Should print -7 26 | # print(f2(7, 9, 1, 3, 4, 9, 0)) # Should print 33 27 | 28 | a = [7, 6, 5, 4] 29 | 30 | def fi2(*argv): 31 | sum = 0 32 | for i in argv: 33 | print(i) 34 | # How do you have to modify the f2 call below to make this work? 35 | print(fi2(a)) # Should print 22 36 | 37 | # Write a function f3 that accepts either one or two arguments. If one argument, 38 | # it returns that value plus 1. If two arguments, it returns the sum of the 39 | # arguments. 40 | # Note: Google "python default arguments" for a hint. 41 | 42 | # YOUR CODE HERE 43 | 44 | def f3(a,b = ""): 45 | if (a in vars() and b in vars()): 46 | return a + b 47 | else: 48 | return a + 1 49 | 50 | print(f3(1, 2)) # Should print 3 51 | print(f3(8)) # Should print 9 52 | 53 | 54 | # Write a function f4 that accepts an arbitrary number of keyword arguments and 55 | # prints out the keys and values like so: 56 | # 57 | # key: foo, value: bar 58 | # key: baz, value: 12 59 | # 60 | # Note: Google "python keyword arguments". 61 | 62 | # YOUR CODE HERE 63 | 64 | def f4(**kwargs): 65 | for key,value in kwargs.items(): 66 | print(F"key {key}, value {value}") 67 | 68 | 69 | # Should print 70 | # key: a, value: 12 71 | # key: b, value: 30 72 | f4(a=12, b=30) 73 | 74 | 75 | # Should print 76 | # key: city, value: Berkeley 77 | # key: population, value: 121240 78 | # key: founded, value: "March 23, 1868" 79 | f4(city="Berkeley", population=121240, founded="March 23, 1868") 80 | 81 | d = { 82 | "monster": "goblin", 83 | "hp": 3 84 | } 85 | 86 | # How do you have to modify the f4 call below to make this work? 87 | f4(**d) 88 | -------------------------------------------------------------------------------- /small bits/12_scopes.py: -------------------------------------------------------------------------------- 1 | # Experiment with scopes in Python. 2 | # Good reading: https://www.programiz.com/python-programming/global-local-nonlocal-variables 3 | 4 | # When you use a variable in a function, it's local in scope to the function. 5 | x = 12 6 | 7 | def change_x(): 8 | global x 9 | x = 99 10 | 11 | change_x() 12 | 13 | # This prints 12. What do we have to modify in change_x() to get it to print 99? 14 | print(x) 15 | 16 | 17 | # This nested function has a similar problem. 18 | 19 | def outer(): 20 | y = 120 21 | 22 | def inner(): 23 | nonlocal y 24 | y = 999 25 | 26 | 27 | inner() 28 | 29 | # This prints 120. What do we have to change in inner() to get it to print 30 | # 999? 31 | # Note: Google "python nested function scope". 32 | print(y) 33 | 34 | 35 | outer() 36 | -------------------------------------------------------------------------------- /small bits/13_file_io.py: -------------------------------------------------------------------------------- 1 | """ 2 | Python makes performing file I/O simple. Take a look 3 | at how to read and write to files here: 4 | 5 | https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files 6 | """ 7 | 8 | # Open up the "foo.txt" file (which already exists) for reading 9 | # Print all the contents of the file, then close the file 10 | # Note: pay close attention to your current directory when trying to open "foo.txt" 11 | 12 | # YOUR CODE HERE 13 | 14 | f = open("foo.txt", "r") 15 | print(f.read()) 16 | f.close() 17 | 18 | # Open up a file called "bar.txt" (which doesn't exist yet) for 19 | # writing. Write three lines of arbitrary content to that file, 20 | # then close the file. Open up "bar.txt" and inspect it to make 21 | # sure that it contains what you expect it to contain 22 | 23 | f = open("bar.txt", "w") 24 | f.write("HEY HEY") 25 | f.close() 26 | 27 | # YOUR CODE HERE -------------------------------------------------------------------------------- /small bits/14_cal.py: -------------------------------------------------------------------------------- 1 | """ 2 | The Python standard library's 'calendar' module allows you to 3 | render a calendar to your terminal. 4 | https://docs.python.org/3.6/library/calendar.html 5 | 6 | Write a program that accepts user input of the form 7 | `14_cal.py [month] [year]` 8 | and does the following: 9 | - If the user doesn't specify any input, your program should 10 | print the calendar for the current month. The 'datetime' 11 | module may be helpful for this. 12 | - If the user specifies one argument, assume they passed in a 13 | month and render the calendar for that month of the current year. 14 | - If the user specifies two arguments, assume they passed in 15 | both the month and the year. Render the calendar for that 16 | month and year. 17 | - Otherwise, print a usage statement to the terminal indicating 18 | the format that your program expects arguments to be given. 19 | Then exit the program. 20 | 21 | Note: the user should provide argument input (in the initial call to run the file) and not 22 | prompted input. Also, the brackets around year are to denote that the argument is 23 | optional, as this is a common convention in documentation. 24 | 25 | This would mean that from the command line you would call `python3 14_cal.py 4 2015` to 26 | print out a calendar for April in 2015, but if you omit either the year or both values, 27 | it should use today’s date to get the month and year. 28 | """ 29 | 30 | import sys 31 | import calendar 32 | from datetime import datetime 33 | 34 | c = calendar.TextCalendar(calendar.SUNDAY) 35 | today = datetime.today() 36 | 37 | if (len(sys.argv) == 1): 38 | str = c.formatmonth(today.year, today.month) 39 | print(str) 40 | elif(len(sys.argv) == 2): 41 | str = c.formatmonth(today.year, int(sys.argv[1])) 42 | print(str) 43 | elif(len(sys.argv) == 3): 44 | str = c.formatmonth(int(sys.argv[2]), int(sys.argv[1])) 45 | print(str) 46 | else: 47 | print("Please use the following format `14_cal.py [month] [year]`") 48 | exit 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /small bits/15_classes.py: -------------------------------------------------------------------------------- 1 | # Make a class LatLon that can be passed parameters `lat` and `lon` to the 2 | # constructor 3 | 4 | # YOUR CODE HERE 5 | 6 | class LatLon: 7 | def __init__(self,lat,lon): 8 | self.lat = lat 9 | self.lon = lon 10 | 11 | 12 | # Make a class Waypoint that can be passed parameters `name`, `lat`, and `lon` to the 13 | # constructor. It should inherit from LatLon. Look up the `super` method. 14 | 15 | # YOUR CODE HERE 16 | 17 | class Waypoint(LatLon): 18 | def __init(self, lat, lon, name): 19 | super().__init__(lat,lon) 20 | self.name = name 21 | 22 | # def __str__(self): 23 | # return '{self.name}, {self.lat}, {self.lon} '.format(self=self) 24 | 25 | # Make a class Geocache that can be passed parameters `name`, `difficulty`, 26 | # `size`, `lat`, and `lon` to the constructor. What should it inherit from? 27 | 28 | # YOUR CODE HERE 29 | 30 | class Geocache(Waypoint): 31 | def __init__(self, name, difficulty, size, lat, lon): 32 | super().__init__(lat, lon, name) 33 | self.difficulty = difficulty 34 | self.size = size 35 | 36 | # def __str__(self): 37 | # return 'f {self.name}, {self.lat}, {self.lon} ' 38 | 39 | 40 | 41 | # Make a new waypoint and print it out: "Catacombs", 41.70505, -121.51521 42 | 43 | waypoint = Waypoint(41, -121, "Catacombs") 44 | 45 | # YOUR CODE HERE 46 | 47 | # Without changing the following line, how can you make it print into something 48 | # more human-readable? Hint: Look up the `object.__str__` method 49 | print(waypoint.name) 50 | 51 | # Make a new geocache "Newberry Views", diff 1.5, size 2, 44.052137, -121.41556 52 | 53 | # YOUR CODE HERE 54 | 55 | # Print it--also make this print more nicely 56 | print(geocache) 57 | -------------------------------------------------------------------------------- /small bits/bar.txt: -------------------------------------------------------------------------------- 1 | HEY HEY -------------------------------------------------------------------------------- /small bits/foo.txt: -------------------------------------------------------------------------------- 1 | Do you bite your thumb at us, sir? 2 | I do bite my thumb, sir. 3 | Do you bite your thumb at us, sir? 4 | No, sir. I do not bite my thumb at you, sir, but I bite my thumb, sir. 5 | Do you quarrel, sir? 6 | Quarrel, sir? No, sir. -------------------------------------------------------------------------------- /small programs/cityreader/cities.csv: -------------------------------------------------------------------------------- 1 | city,state_name,county_name,lat,lng,population,density,timezone,zips 2 | Seattle,Washington,King,47.6217,-122.3238,3541236,3243,America/Los_Angeles,98109 98108 98104 98107 98106 98101 98103 98102 98105 98154 98122 98121 98126 98125 98178 98174 98177 98144 98146 98195 98199 98118 98119 98116 98117 98115 98112 98164 98134 98136 98133 98111 98113 98114 98124 98127 98129 98139 98141 98145 98161 98165 98170 98175 98181 98185 98191 98194 3 | Richmond,Virginia,Richmond (city),37.5294,-77.4755,1041877,1440,America/New_York,23219 23222 23223 23220 23221 23226 23227 23224 23225 23230 23235 23234 23173 23218 23232 23241 23242 23249 23255 23260 23261 23269 23273 23274 23276 23278 23279 23282 23284 23285 23286 23288 23289 23290 23291 23292 23293 23295 23297 23298 4 | Virginia Beach,Virginia,Virginia Beach (city),36.7335,-76.0435,1487505,699,America/New_York,23459 23451 23453 23452 23455 23457 23456 23454 23460 23461 23462 23464 23450 23458 23463 23465 23466 23467 23471 23479 5 | Washington,District of Columbia,District of Columbia,38.9047,-77.0163,5191844,4301,America/New_York,20010 20011 20012 20015 20228 20520 20307 20418 20319 20020 20024 20510 20593 20540 20240 20245 20202 20390 20007 20006 20004 20003 20002 20001 20009 20008 20535 20317 20405 20057 20052 20053 20017 20018 20565 20566 20560 20064 20551 20553 20019 20230 20373 20260 20427 20005 20032 20036 20037 20204 20506 20045 20016 20013 20022 20026 20027 20029 20030 20033 20035 20038 20039 20040 20041 20042 20043 20044 20047 20049 20050 20055 20056 20058 20059 20060 20061 20062 20063 20065 20066 20067 20068 20069 20070 20071 20073 20074 20075 20076 20077 20078 20080 20081 20082 20090 20091 20189 20201 20203 20206 20207 20208 20210 20211 20212 20213 20214 20215 20216 20217 20218 20219 20220 20221 20222 20223 20224 20226 20227 20229 20232 20233 20235 20237 20238 20239 20241 20242 20244 20250 20251 20252 20254 20261 20262 20265 20266 20268 20270 20277 20289 20299 20301 20303 20306 20310 20314 20318 20330 20340 20350 20355 20370 20372 20374 20375 20376 20380 20388 20389 20391 20392 20393 20394 20395 20398 20401 20402 20403 20404 20406 20407 20408 20409 20410 20411 20412 20413 20414 20415 20416 20417 20419 20420 20421 20422 20423 20424 20425 20426 20428 20429 20431 20433 20434 20435 20436 20437 20439 20440 20441 20442 20444 20447 20451 20453 20456 20460 20463 20468 20469 20470 20472 20500 20501 20502 20503 20504 20505 20507 20508 20509 20511 20515 20521 20522 20523 20524 20525 20526 20527 20528 20529 20530 20531 20533 20534 20536 20537 20538 20539 20541 20542 20543 20544 20546 20547 20548 20549 20552 20554 20555 20557 20559 20570 20571 20572 20573 20575 20576 20577 20578 20579 20580 20581 20585 20586 20588 20590 20591 20594 20597 20599 56901 56902 56904 56908 56915 56920 56933 56935 56944 56945 56950 56965 56967 56972 56998 56999 6 | Milwaukee,Wisconsin,Milwaukee,43.0640,-87.9669,1377104,2388,America/Chicago,53203 53202 53207 53206 53205 53204 53209 53208 53233 53211 53218 53219 53214 53215 53216 53210 53212 53213 53295 53225 53224 53227 53226 53221 53220 53223 53222 53228 53201 53234 53237 53259 53263 53274 53278 53288 53290 53293 7 | Orlando,Florida,Orange,28.4801,-81.3448,1757288,1041,America/New_York,32829 32827 32824 32822 32804 32805 32806 32807 32801 32803 32808 32839 32835 32832 32819 32812 32811 32814 32802 32816 32834 32853 32854 32855 32856 32857 32858 32859 32860 32861 32862 32867 32868 32869 32872 32877 32878 32885 32886 32887 32891 32897 8 | Miami,Florida,Miami-Dade,25.7840,-80.2102,6247425,4866,America/New_York,33129 33125 33126 33127 33128 33149 33144 33145 33142 33139 33138 33137 33136 33135 33134 33133 33132 33131 33130 33150 33101 33109 33102 33111 33114 33116 33119 33124 33151 33152 33153 33163 33164 33188 33192 33195 33197 33199 33222 33231 33233 33234 33238 33239 33242 33243 33245 33247 33255 33256 33257 33261 33265 33266 33269 33280 33283 33296 33299 9 | Tampa,Florida,Hillsborough,27.9937,-82.4454,2744107,1283,America/New_York,33637 33629 33621 33620 33647 33602 33619 33616 33613 33611 33617 33614 33610 33612 33605 33604 33609 33607 33606 33603 33601 33608 33622 33623 33630 33631 33633 33646 33650 33655 33660 33661 33662 33663 33664 33672 33673 33674 33675 33677 33679 33680 33681 33682 33684 33685 33686 33687 33688 33689 33694 10 | Jacksonville,Florida,Duval,30.3322,-81.6749,1141459,454,America/New_York,32224 32225 32226 32227 32220 32221 32222 32223 32228 32219 32218 32217 32216 32211 32210 32212 32246 32244 32233 32234 32206 32205 32202 32250 32254 32257 32256 32208 32209 32204 32258 32277 32207 32099 32201 32203 32214 32229 32231 32232 32235 32236 32237 32238 32239 32241 32245 32247 32255 32260 11 | Albuquerque,New Mexico,Bernalillo,35.1055,-106.6476,759517,1147,America/Denver,87121 87123 87112 87113 87110 87111 87116 87114 87109 87108 87102 87105 87104 87107 87106 87120 87101 87103 87115 87119 87125 87131 87151 87153 87154 87158 87176 87181 87184 87185 87187 87190 87191 87192 87193 87194 87195 87196 87197 87198 87199 12 | Fort Worth,Texas,Tarrant,32.7813,-97.3466,854113,968,America/Chicago,76164 76040 76134 76135 76137 76131 76132 76133 76109 76108 76105 76104 76107 76103 76102 76155 76106 76053 76052 76123 76120 76244 76006 76008 76179 76177 76036 76140 76262 76127 76118 76119 76116 76117 76114 76115 76112 76110 76111 76129 76101 76113 76121 76122 76124 76130 76136 76147 76150 76161 76162 76163 76166 76181 76185 76191 76192 76193 76195 76196 76197 76198 76199 13 | McAllen,Texas,Hidalgo,26.2203,-98.2457,798187,1113,America/Chicago,78504 78503 78501 78502 78505 14 | El Paso,Texas,El Paso,31.8478,-106.4310,845059,1027,America/Denver,79901 79902 79903 79904 79905 79906 79907 79930 79932 79935 79934 79936 79912 79911 79835 79922 79920 79927 79924 79925 79915 79910 79913 79914 79917 79918 79923 79926 79929 79931 79937 79940 79941 79943 79944 79945 79946 79947 79948 79949 79950 79951 79952 79953 79954 79955 79958 79960 79961 79968 79976 79978 79980 79995 79996 79997 79998 79999 88510 88511 88512 88513 88514 88515 88517 88518 88519 88520 88521 88523 88524 88525 88526 88527 88528 88529 88530 88531 88532 88533 88534 88535 88536 88538 88539 88540 88541 88542 88543 88544 88545 88546 88547 88548 88549 88550 88553 88554 88555 88556 88557 88558 88559 88560 88561 88562 88563 88565 88566 88567 88568 88569 88570 88571 88572 88573 88574 88575 88576 88577 88578 88579 88580 88581 88582 88583 88584 88585 88586 88587 88588 88589 88590 88595 15 | Dallas,Texas,Dallas,32.7938,-96.7659,5634307,1490,America/Chicago,75287 75098 75233 75231 75234 75254 75251 75252 75253 75032 75227 75238 75232 75230 75236 75237 75235 75088 75087 75243 75247 75244 75249 75248 75051 75210 75211 75212 75214 75215 75216 75217 75218 75219 75390 75182 75229 75228 75220 75223 75225 75224 75226 75241 75240 75246 75043 75166 75270 75207 75206 75205 75204 75203 75202 75201 75209 75208 75019 75221 75222 75242 75250 75260 75261 75262 75263 75264 75265 75266 75267 75275 75277 75283 75284 75285 75301 75303 75312 75313 75315 75320 75326 75336 75339 75342 75354 75355 75356 75357 75358 75359 75360 75367 75368 75370 75371 75372 75373 75374 75376 75378 75379 75380 75381 75382 75389 75391 75392 75393 75394 75395 75397 75398 16 | Austin,Texas,Travis,30.3038,-97.7545,1633847,1170,America/Chicago,78749 78748 78741 78742 78745 78744 78747 78746 78717 78712 78719 78617 78739 78735 78730 78731 78732 78733 78705 78704 78701 78703 78702 78758 78759 78752 78753 78750 78751 78756 78757 78754 78652 78723 78722 78721 78727 78726 78725 78724 78729 78728 73301 73344 78651 78708 78709 78710 78711 78713 78714 78715 78716 78718 78720 78755 78760 78761 78762 78763 78764 78765 78766 78767 78768 78769 78772 78773 78774 78778 78779 78783 78799 17 | Houston,Texas,Harris,29.7871,-95.3936,5424720,1412,America/Chicago,77069 77068 77061 77060 77063 77062 77065 77064 77067 77066 77346 77036 77037 77034 77035 77032 77033 77030 77031 77038 77449 77489 77046 77044 77040 77048 77201 77598 77018 77019 77015 77016 77017 77010 77011 77012 77013 77092 77093 77345 77546 77080 77025 77024 77027 77026 77021 77020 77023 77022 77029 77028 77094 77096 77090 77091 77098 77099 77078 77079 77072 77073 77070 77071 77076 77077 77074 77075 77407 77047 77045 77043 77041 77336 77339 77338 77003 77002 77007 77006 77005 77004 77009 77008 77450 77084 77089 77088 77083 77082 77081 77087 77086 77085 77042 77053 77054 77055 77056 77057 77058 77059 77396 77050 77051 77504 77001 77052 77202 77203 77204 77205 77206 77207 77208 77209 77210 77212 77213 77215 77216 77217 77218 77219 77220 77221 77222 77223 77224 77225 77226 77227 77228 77229 77230 77231 77233 77234 77235 77236 77237 77238 77240 77241 77242 77243 77244 77245 77248 77249 77251 77252 77253 77254 77255 77256 77257 77258 77259 77261 77262 77263 77265 77266 77267 77268 77269 77270 77271 77272 77273 77274 77275 77277 77279 77280 77282 77284 77287 77288 77289 77290 77291 77292 77293 77297 77299 77315 77411 18 | San Antonio,Texas,Bexar,29.4722,-98.5247,1976787,1250,America/Chicago,78112 78233 78259 78258 78252 78251 78250 78257 78256 78255 78254 78208 78201 78202 78203 78204 78205 78207 78231 78230 78232 78235 78234 78237 78239 78238 78209 78109 78266 78260 78219 78218 78217 78216 78215 78214 78213 78212 78211 78210 78244 78245 78247 78240 78242 78248 78249 78023 78222 78223 78220 78221 78226 78227 78224 78225 78228 78229 78054 78206 78241 78246 78265 78268 78269 78270 78278 78279 78280 78283 78284 78285 78288 78289 78291 78292 78293 78294 78295 78296 78297 78298 78299 19 | New Orleans,Louisiana,Orleans,30.0687,-89.9288,1024421,892,America/Chicago,70139 70130 70131 70114 70115 70116 70117 70112 70113 70118 70119 70129 70128 70125 70124 70127 70126 70122 70163 70141 70142 70143 70145 70146 70148 70150 70151 70152 70153 70154 70156 70157 70158 70159 70160 70161 70162 70164 70165 70166 70167 70170 70172 70174 70175 70176 70177 70178 70179 70181 70182 70183 70184 70185 70186 70187 70189 70190 70195 20 | Charlotte,North Carolina,Mecklenburg,35.2080,-80.8308,1438351,1065,America/New_York,28269 28262 28105 28280 28282 28209 28208 28205 28204 28207 28206 28203 28202 28227 28226 28278 28270 28273 28277 28134 28216 28217 28214 28215 28212 28213 28210 28211 28244 28126 28130 28201 28218 28219 28220 28221 28222 28223 28224 28228 28229 28230 28231 28232 28233 28234 28235 28236 28237 28241 28242 28243 28246 28247 28253 28254 28255 28256 28258 28260 28263 28265 28266 28271 28272 28274 28275 28281 28284 28285 28287 28288 28289 28290 28296 28297 28299 21 | Raleigh,North Carolina,Wake,35.8323,-78.6441,1005457,1225,America/New_York,27617 27616 27615 27614 27613 27612 27610 27608 27609 27601 27603 27604 27605 27606 27607 27602 27611 27619 27620 27621 27622 27623 27624 27625 27626 27627 27628 27629 27634 27635 27636 27640 27650 27656 27658 27661 27668 27675 27676 27690 27695 27697 27698 27699 22 | Omaha,Nebraska,Douglas,41.2634,-96.0453,792463,1295,America/Chicago,68116 68118 68106 68107 68105 68108 68178 68111 68122 68127 68124 68110 68112 68114 68117 68022 68132 68144 68137 68135 68134 68131 68130 68102 68104 68164 68152 68154 68101 68103 68109 68119 68139 68145 68172 68175 68176 68179 68180 68182 68183 68198 23 | Memphis,Tennessee,Shelby,35.1047,-89.9773,1069661,794,America/Chicago,38122 38125 38127 38107 38106 38105 38104 38103 38109 38108 38152 38132 38133 38131 38141 38111 38112 38114 38115 38116 38117 38118 38119 38018 38016 38134 38128 38120 38126 37501 37544 38101 38113 38124 38130 38136 38137 38145 38148 38150 38151 38157 38159 38161 38163 38166 38167 38168 38173 38174 38175 38177 38181 38182 38184 38186 38187 38188 38190 38193 38194 38197 24 | Nashville,Tennessee,Davidson,36.1714,-86.7844,1065078,535,America/Chicago,37027 37138 37076 37072 37201 37203 37206 37240 37243 37246 37080 37218 37219 37216 37217 37214 37215 37212 37213 37210 37211 37189 37209 37208 37205 37204 37207 37115 37013 37228 37221 37220 37143 37011 37116 37202 37222 37224 37227 37229 37230 37232 37234 37235 37236 37238 37241 37242 37244 37250 25 | Buffalo,New York,Erie,42.9016,-78.8487,920136,2456,America/New_York,14208 14209 14202 14203 14201 14206 14207 14204 14220 14222 14218 14211 14210 14213 14212 14215 14214 14216 14205 14231 14233 14240 14241 14260 14263 14264 14265 14267 14269 14270 14272 14273 14276 14280 26 | Queens,New York,Queens,40.7498,-73.7976,2333054,8247,America/New_York,11361 11362 11363 11364 11354 11355 11356 11357 11358 11359 11360 11365 11366 11367 11412 11423 11432 11433 11434 11435 11436 11101 11102 11103 11104 11105 11106 11374 11375 11379 11385 11691 11692 11693 11694 11695 11697 11004 11005 11411 11413 11422 11426 11427 11428 11429 11414 11415 11416 11417 11418 11419 11420 11421 11368 11369 11370 11372 11373 11377 11378 27 | New York,New York,New York,40.6943,-73.9249,19164071,10934,America/New_York,11229 11226 11225 11224 11222 11221 11220 11385 10169 10168 10167 10165 10162 10282 10280 10040 10044 11109 11102 11103 11104 11105 11379 11378 11697 11694 11692 11693 11691 10271 10279 10278 10075 10302 10452 11451 10475 10474 10471 10470 10473 10472 11228 11223 10103 11368 11369 11366 11367 11365 11362 11363 11360 11361 10028 10029 10026 10027 10024 10025 10022 10023 10020 10021 11212 11213 11210 11211 11216 11217 11214 11215 11218 11219 10152 10153 10154 10306 10305 10310 10311 10312 10314 11432 11433 11430 11436 11434 11435 10453 10451 10457 10456 10455 10454 10459 10458 10128 10004 10005 10006 10007 10001 10002 10003 10009 11238 11239 11230 11231 11232 11233 11234 11235 11236 11237 11375 11374 11377 11371 11370 11373 11372 10170 10171 10172 10173 10174 10177 11351 10039 10038 10035 10034 10037 10036 10031 10030 10033 10032 11201 11208 11203 11205 11204 11207 11206 11209 11411 11412 11413 11414 11415 11416 11417 11418 11419 11101 11106 11001 11005 11004 10065 10069 10199 10309 10308 10307 10304 10303 10301 11429 11428 11421 11420 11423 11422 11425 11424 11427 11426 10466 10467 10464 10465 10462 10463 10460 10461 10468 10469 10119 10115 10112 10110 10111 11364 11359 11358 11357 11356 11355 11354 10019 10018 10013 10012 10011 10010 10017 10016 10014 10008 10041 10043 10045 10055 10060 10080 10081 10087 10090 10101 10102 10104 10105 10106 10107 10108 10109 10113 10114 10116 10117 10118 10120 10121 10122 10123 10124 10125 10126 10129 10130 10131 10132 10133 10138 10150 10151 10155 10156 10157 10158 10159 10160 10163 10164 10166 10175 10176 10178 10179 10185 10203 10211 10212 10213 10242 10249 10256 10258 10259 10260 10261 10265 10268 10269 10270 10272 10273 10274 10275 10276 10277 10281 10285 10286 10313 11120 11202 11241 11242 11243 11245 11247 11249 11251 11252 11256 11352 11380 11381 11386 11405 11431 11439 11499 11690 11695 28 | Bronx,New York,Bronx,40.8501,-73.8662,1455720,13202,America/New_York,10453 10457 10460 10458 10467 10468 10451 10452 10456 10454 10455 10459 10474 10463 10471 10466 10469 10470 10475 10461 10462 10464 10465 10472 10473 29 | Brooklyn,New York,Kings,40.6501,-73.9496,2629150,14606,America/New_York,11212 11213 11216 11233 11238 11209 11214 11228 11204 11218 11219 11230 11234 11236 11239 11223 11224 11229 11235 11201 11205 11215 11217 11231 11203 11210 11225 11226 11207 11208 11211 11222 11220 11232 11206 11221 11237 30 | Manhattan,New York,New York,40.7834,-73.9662,1643734,27799,America/New_York,10026 10027 10030 10037 10039 10001 10011 10018 10019 10020 10036 10029 10035 10010 10016 10017 10022 10012 10013 10014 10004 10005 10006 10007 10038 10280 10002 10003 10009 10021 10028 10044 10065 10075 10128 10023 10024 10025 10031 10032 10033 10034 10040 31 | Philadelphia,Pennsylvania,Philadelphia,40.0076,-75.1340,5591554,4511,America/New_York,19154 19151 19150 19153 19152 19102 19103 19106 19107 19104 19109 19128 19129 19120 19121 19122 19123 19124 19125 19126 19127 19112 19111 19115 19114 19116 19119 19118 19148 19149 19146 19147 19144 19145 19142 19143 19140 19141 19139 19138 19137 19136 19135 19134 19133 19132 19131 19130 19019 19092 19093 19099 19101 19105 19108 19110 19155 19160 19161 19162 19170 19171 19172 19173 19175 19176 19177 19178 19179 19181 19182 19183 19184 19185 19187 19188 19190 19191 19192 19193 19194 19195 19196 19197 19244 19255 32 | Pittsburgh,Pennsylvania,Allegheny,40.4396,-79.9763,1722206,2116,America/New_York,15216 15217 15214 15212 15210 15211 15218 15219 15290 15233 15260 15232 15205 15204 15207 15206 15201 15203 15208 15224 15213 15234 15222 15221 15220 15226 15120 15230 15231 15240 15242 15244 15250 15251 15252 15253 15254 15255 15257 15258 15259 15261 15262 15264 15265 15267 15268 15270 15272 15274 15275 15276 15277 15278 15279 15281 15282 15283 15286 15289 15295 33 | Sacramento,California,Sacramento,38.5666,-121.4683,1830061,1952,America/Los_Angeles,95821 95823 95838 95832 95833 95831 95834 95835 95811 95814 95815 95816 95818 95819 95828 95820 95822 95825 95824 95826 95817 94203 94204 94205 94207 94208 94209 94211 94229 94230 94232 94234 94235 94236 94237 94239 94240 94244 94245 94247 94248 94249 94250 94252 94254 94256 94257 94258 94259 94261 94262 94263 94267 94268 94269 94271 94273 94274 94277 94278 94279 94280 94282 94283 94284 94285 94286 94287 94288 94289 94290 94291 94293 94294 94295 94296 94297 94298 94299 95812 95813 95840 95851 95852 95853 95867 95894 34 | Riverside,California,Riverside,33.9382,-117.3949,2065627,1544,America/Los_Angeles,92508 92503 92501 92505 92504 92507 92506 92502 92513 92514 92516 92517 92521 92522 35 | San Francisco,California,San Francisco,37.7561,-122.4429,3548847,7170,America/Los_Angeles,94130 94131 94132 94133 94134 94108 94103 94102 94105 94104 94158 94124 94123 94122 94121 94129 94110 94118 94112 94116 94117 94114 94115 94111 94109 94107 94127 94119 94120 94125 94126 94137 94139 94140 94141 94142 94143 94144 94145 94146 94147 94151 94159 94160 94161 94163 94164 94172 94177 94188 36 | San Diego,California,San Diego,32.8312,-117.1225,3181172,1670,America/Los_Angeles,92109 92108 92106 92103 92111 92117 92154 92140 92107 92105 92104 92102 92071 92132 92130 92131 92134 92139 92025 92027 92147 92145 92014 92119 92110 92121 92120 92123 92122 92124 92127 92126 92129 92128 92101 92037 92173 92113 92114 92115 92116 92038 92039 92072 92092 92093 92112 92137 92138 92142 92143 92149 92150 92152 92153 92158 92159 92160 92161 92163 92165 92166 92167 92168 92169 92170 92171 92172 92174 92175 92176 92177 92179 92182 92186 92187 92190 92191 92192 92193 92195 92196 92197 92198 92199 37 | San Jose,California,Santa Clara,37.3020,-121.8488,1804359,2242,America/Los_Angeles,95118 95128 95124 95125 95126 95127 95120 95123 95008 95002 95117 95116 95111 95110 95113 95112 95119 95121 95148 95133 95132 95131 95130 95136 95135 95134 95139 95138 95037 95013 95129 95122 95101 95103 95106 95109 95115 95141 95150 95151 95153 95154 95155 95156 95157 95158 95159 95160 95161 95164 95170 95172 95173 95190 95191 95192 95193 95194 95196 38 | Los Angeles,California,Los Angeles,34.1140,-118.4068,12740381,3275,America/Los_Angeles,90291 90293 90292 90029 91316 91311 90035 90008 90004 90005 90006 90007 90001 90002 90003 90710 90089 91306 91307 91344 91345 91340 91342 91343 90034 90037 90036 90031 90033 90039 90038 90247 90248 91411 91436 91371 91608 91605 91604 91607 91606 91601 91602 90402 90068 90062 90063 90061 90066 90067 90064 90065 91326 91324 91325 90013 90012 90011 90017 90016 90015 90014 90028 90090 90095 90094 91042 91040 90069 91352 91356 91402 90041 90042 90043 90044 90045 90046 90047 90048 90049 90019 90018 90010 91423 90210 91303 91304 90079 90071 90077 90059 91331 91330 91335 90026 90027 90024 90025 90023 90020 90021 90272 90732 90731 90230 91406 91405 91403 91401 91367 91364 90032 90057 90058 90744 90501 90502 90009 90030 90050 90051 90053 90054 90055 90070 90072 90074 90075 90076 90078 90080 90081 90082 90083 90084 90086 90087 90088 90093 90099 90189 90213 90294 90296 90733 90734 90748 91041 91043 91305 91308 91309 91313 91327 91328 91329 91333 91334 91337 91346 91353 91357 91365 91392 91393 91394 91395 91396 91404 91407 91408 91409 91410 91412 91413 91416 91426 91470 91482 91495 91496 91499 91603 91609 91610 91611 91612 91614 91615 91616 91617 91618 39 | Las Vegas,Nevada,Clark,36.2288,-115.2603,2044731,1829,America/Los_Angeles,89149 89107 89106 89104 89102 89101 89108 89138 89130 89131 89134 89143 89146 89145 89144 89124 89110 89117 89129 89128 88901 88905 89114 89116 89125 89127 89133 89137 89151 89152 89153 89155 89158 89163 89164 89180 89185 89195 40 | Denver,Colorado,Denver,39.7621,-104.8759,2741534,1745,America/Denver,80264 80218 80230 80231 80236 80237 80235 80238 80239 80123 80249 80247 80246 80290 80293 80294 80219 80210 80211 80212 80216 80221 80220 80223 80222 80224 80227 80209 80207 80206 80205 80204 80202 80014 80203 80201 80208 80217 80225 80243 80244 80248 80250 80251 80252 80256 80257 80259 80261 80262 80263 80265 80266 80271 80273 80274 80281 80291 80299 41 | Chicago,Illinois,Cook,41.8373,-87.6861,8639278,4585,America/Chicago,60018 60649 60641 60640 60643 60642 60645 60644 60647 60646 60616 60617 60614 60615 60612 60613 60610 60611 60618 60619 60631 60827 60638 60639 60634 60636 60637 60630 60632 60633 60605 60604 60607 60606 60601 60603 60602 60609 60608 60106 60661 60660 60659 60652 60653 60656 60657 60654 60655 60651 60623 60622 60621 60620 60626 60625 60624 60629 60628 60707 60664 60666 60668 60669 60670 60673 60674 60675 60677 60678 60680 60681 60684 60685 60686 60687 60688 60689 60690 60691 60693 60694 60695 60696 60697 60699 60701 42 | Atlanta,Georgia,Fulton,33.7627,-84.4231,5080712,1370,America/New_York,30334 30331 30332 30309 30308 30307 30303 30354 30327 30326 30324 30319 30316 30342 30305 30306 30317 30314 30315 30312 30313 30310 30311 30363 30318 30301 30302 30304 30321 30325 30343 30348 30353 30355 30357 30358 30361 30362 30368 30369 30370 30371 30375 30377 30378 30380 30385 30388 30392 30394 30396 30398 31106 31107 31119 31126 31131 31139 31141 31145 31146 31150 31156 31192 31193 31195 31196 39901 43 | Indianapolis,Indiana,Marion,39.7771,-86.1458,1550488,913,America/Indiana/Indianapolis,46237 46218 46219 46217 46214 46260 46268 46226 46224 46229 46228 46183 46231 46234 46235 46236 46239 46254 46208 46201 46203 46202 46205 46204 46256 46250 46259 46227 46225 46222 46221 46220 46113 46278 46241 46240 46206 46207 46209 46210 46211 46230 46242 46244 46247 46249 46251 46253 46255 46262 46274 46275 46277 46282 46283 46285 46291 46296 46298 44 | Oklahoma City,Oklahoma,Oklahoma,35.4677,-97.5138,948154,406,America/Chicago,73012 73099 73097 73119 73118 73114 73117 73116 73111 73112 73020 73173 73013 73142 73141 73145 73149 73078 73106 73107 74857 73139 73132 73131 73135 73134 73008 73084 73105 73102 73162 73054 73151 73150 73159 73064 73108 73109 73104 73103 73129 73179 73170 73049 73169 73165 73127 73120 73121 73122 73128 73101 73113 73123 73124 73125 73126 73136 73137 73140 73143 73144 73146 73147 73148 73152 73153 73154 73155 73156 73157 73163 73164 73167 73172 73178 73184 73189 73190 73194 73195 73196 45 | Phoenix,Arizona,Maricopa,33.5722,-112.0891,4054083,1204,America/Phoenix,85008 85009 85003 85006 85007 85004 85083 85086 85087 85085 85383 85304 85306 85308 85020 85021 85022 85023 85024 85027 85028 85029 85353 85013 85015 85014 85254 85044 85045 85042 85043 85040 85041 85048 85054 85037 85035 85034 85033 85032 85031 85019 85018 85012 85017 85016 85307 85310 85051 85050 85053 85001 85002 85005 85010 85011 85025 85026 85030 85036 85038 85046 85060 85061 85062 85063 85064 85065 85066 85067 85068 85069 85070 85071 85072 85073 85074 85075 85076 85078 85079 85080 85082 85098 46 | Tucson,Arizona,Pima,32.1558,-110.8777,860333,887,America/Phoenix,85705 85707 85706 85756 85723 85726 85724 85701 85708 85748 85745 85747 85716 85714 85715 85712 85713 85710 85711 85719 85730 85702 85703 85709 85717 85720 85721 85722 85725 85731 85732 85738 85751 85754 85775 47 | Bridgeport,Connecticut,Fairfield,41.1909,-73.1958,934289,3508,America/New_York,06605 06604 06607 06606 06608 06610 06601 06602 06673 06699 48 | Hartford,Connecticut,Hartford,41.7661,-72.6834,913587,2737,America/New_York,06106 06105 06103 06120 06112 06160 06114 06101 06102 06104 06115 06123 06126 06132 06134 06140 06141 06142 06143 06144 06145 06146 06147 06150 06151 06152 06153 06154 06155 06156 06161 06167 06176 06180 06183 06199 49 | Baltimore,Maryland,Baltimore (city),39.3051,-76.6144,2181206,2931,America/New_York,21218 21211 21210 21213 21212 21215 21214 21217 21216 21231 21230 21239 21251 21209 21202 21206 21207 21205 21226 21201 21223 21224 21225 21229 21203 21233 21235 21241 21263 21264 21270 21273 21275 21278 21279 21280 21281 21282 21284 21285 21287 21288 21289 21290 21297 21298 50 | Boston,Massachusetts,Suffolk,42.3189,-71.0838,4556916,5373,America/New_York,02120 02121 02122 02124 02125 02126 02127 02128 02129 02210 02215 02467 02119 02118 02111 02110 02113 02115 02114 02116 02199 02134 02136 02135 02132 02131 02130 02203 02163 02152 02108 02109 02112 02117 02123 02133 02137 02196 02201 02204 02205 02206 02211 02212 02217 02222 02241 02266 02283 02284 02293 02297 02298 51 | Cleveland,Ohio,Cuyahoga,41.4766,-81.6805,1731637,1917,America/New_York,44135 44128 44120 44119 44113 44112 44111 44110 44115 44114 44144 44127 44104 44105 44106 44101 44102 44103 44108 44109 44181 44188 44190 44191 44192 44193 44194 44195 44197 44198 44199 52 | Columbus,Ohio,Franklin,39.9859,-82.9852,1495146,1522,America/New_York,43026 43109 43054 43220 43221 43222 43223 43224 43081 43228 43227 43210 43213 43212 43215 43214 43217 43219 43002 43004 43068 43085 43240 43229 43235 43232 43231 43230 43119 43110 43017 43016 43137 43211 43202 43203 43201 43206 43207 43204 43205 43209 43216 43218 43226 43234 43236 43251 43260 43266 43268 43270 43271 43272 43279 43287 43291 53 | Cincinnati,Ohio,Hamilton,39.1412,-84.5060,1634573,1480,America/New_York,45219 45213 45212 45211 45217 45216 45214 45225 45229 45226 45227 45224 45204 45205 45206 45207 45202 45203 45208 45209 45223 45239 45238 45237 45220 45230 45233 45232 45201 45221 45222 45234 45235 45250 45253 45254 45258 45262 45263 45264 45267 45268 45269 45270 45271 45273 45274 45275 45277 45296 45298 45299 45999 54 | Salt Lake City,Utah,Salt Lake,40.7774,-111.9301,1061156,672,America/Denver,84116 84115 84113 84112 84111 84144 84128 84180 84108 84101 84102 84103 84104 84105 84106 84110 84114 84122 84132 84133 84134 84136 84138 84139 84143 84145 84147 84148 84150 84151 84152 84158 84189 84190 84199 55 | Saint Louis,Missouri,St. Louis (city),38.6358,-90.2451,2096990,1940,America/Chicago,63110 63111 63112 63113 63115 63116 63118 63120 63107 63106 63104 63103 63102 63101 63109 63108 63155 63139 63137 63143 63147 63145 63150 63151 63156 63157 63158 63160 63163 63164 63166 63167 63169 63171 63177 63178 63179 63180 63182 63188 63195 63197 63199 56 | Kansas City,Missouri,Jackson,39.1239,-94.5541,1590762,590,America/Chicago,64163 64164 64165 64167 64161 64053 64119 64118 64151 64153 64155 64154 64157 64156 64158 64108 64109 64102 64105 64101 64128 64124 64125 64126 64127 64120 64123 64129 64166 64192 64114 64117 64116 64111 64110 64113 64112 64132 64130 64146 64145 64149 64147 64106 64139 64138 64133 64131 64137 64136 64134 64121 64141 64144 64148 64162 64168 64170 64171 64179 64180 64184 64187 64188 64190 64191 64195 64196 64197 64198 64199 64999 57 | Minneapolis,Minnesota,Hennepin,44.9635,-93.2679,2866604,2957,America/Chicago,55402 55409 55408 55407 55406 55405 55404 55403 55401 55417 55455 55430 55454 55418 55419 55410 55411 55412 55413 55414 55415 55416 55440 55458 55459 55460 55467 55470 55472 55473 55474 55478 55479 55480 55483 55484 55485 55486 55487 55488 58 | Detroit,Michigan,Wayne,42.3834,-83.1024,3520589,1872,America/Detroit,48209 48208 48201 48207 48206 48205 48204 48203 48238 48239 48234 48235 48233 48202 48243 48214 48215 48216 48217 48210 48211 48212 48213 48219 48228 48224 48227 48226 48221 48223 48222 48231 48232 48244 48255 48260 48264 48265 48266 48267 48268 48269 48272 48275 48277 48278 48279 48288 59 | Providence,Rhode Island,Providence,41.8229,-71.4186,1198789,3760,America/New_York,02903 02906 02907 02904 02905 02908 02909 02912 02901 02902 02918 02940 60 | Louisville,Kentucky,Jefferson,38.1662,-85.6488,1003412,902,America/New_York,40177 40245 40241 40218 40219 40214 40216 40211 40213 40059 40291 40299 40220 40223 40222 40229 40228 40023 40272 40207 40209 40258 40118 40018 40027 61 | Portland,Oregon,Multnomah,45.5372,-122.6500,2027629,1851,America/Los_Angeles,97227 97221 97220 97229 97203 97202 97201 97206 97205 97204 97209 97208 97266 97219 97212 97236 97232 97233 97230 97239 97218 97214 97215 97216 97217 97210 97211 97213 97207 97228 97238 97240 97242 97250 97251 97252 97253 97254 97256 97258 97280 97282 97283 97286 97290 97291 97292 97293 97294 97296 62 | -------------------------------------------------------------------------------- /small programs/cityreader/cityreader.py: -------------------------------------------------------------------------------- 1 | # Create a class to hold a city location. Call the class "City". It should have 2 | # fields for name, lat and lon (representing latitude and longitude). 3 | 4 | import csv 5 | 6 | class City(): 7 | def __init__(self, name, lat, lon): 8 | self.name = name 9 | self.lat = lat 10 | self.lon = lon 11 | 12 | def __str__(self): 13 | return f"This is {self.name}, lon {self.lon}, lat {self.lat}" 14 | 15 | 16 | # We have a collection of US cities with population over 750,000 stored in the 17 | # file "cities.csv". (CSV stands for "comma-separated values".) 18 | # 19 | # In the body of the `cityreader` function, use Python's built-in "csv" module 20 | # to read this file so that each record is imported into a City instance. Then 21 | # return the list with all the City instances from the function. 22 | # Google "python 3 csv" for references and use your Google-fu for other examples. 23 | 24 | def cityreader(): 25 | # csv.reader() 26 | arr = [] 27 | with open('cities.csv', newline="") as csvfile: 28 | csvreader = csv.reader(csvfile, delimiter = ",") 29 | for row in csvreader: 30 | newCity = City(row[0], row[3], row[4]) 31 | arr.append(newCity) 32 | return arr 33 | 34 | 35 | 36 | # 37 | # Store the instances in the "cities" list, below. 38 | # 39 | # Note that the first line of the CSV is header that describes the fields--this 40 | # should not be loaded into a City object. 41 | cities = cityreader() 42 | 43 | # for city in cities: 44 | # print (city.intro()) 45 | 46 | # def cityreader(cities=[]): 47 | # # TODO Implement the functionality to read from the 'cities.csv' file 48 | # # Ensure that the lat and lon valuse are all floats 49 | # # For each city record, create a new City instance and add it to the 50 | # # `cities` list 51 | 52 | # return cities 53 | 54 | # cityreader(cities) 55 | 56 | # Print the list of cities (name, lat, lon), 1 record per line. 57 | for c in cities: 58 | print(c) 59 | 60 | # STRETCH GOAL! 61 | # 62 | # Allow the user to input two points, each specified by latitude and longitude. 63 | # These points form the corners of a lat/lon square. Pass these latitude and 64 | # longitude values as parameters to the `cityreader_stretch` function, along 65 | # with the `cities` list that holds all the City instances from the `cityreader` 66 | # function. This function should output all the cities that fall within the 67 | # coordinate square. 68 | # 69 | # Be aware that the user could specify either a lower-left/upper-right pair of 70 | # coordinates, or an upper-left/lower-right pair of coordinates. Hint: normalize 71 | # the input data so that it's always one or the other, then search for cities. 72 | # In the example below, inputting 32, -120 first and then 45, -100 should not 73 | # change the results of what the `cityreader_stretch` function returns. 74 | # 75 | # Example I/O: 76 | # 77 | # Enter lat1,lon1: 45,-100 78 | # Enter lat2,lon2: 32,-120 79 | # Albuquerque: (35.1055,-106.6476) 80 | # Riverside: (33.9382,-117.3949) 81 | # San Diego: (32.8312,-117.1225) 82 | # Los Angeles: (34.114,-118.4068) 83 | # Las Vegas: (36.2288,-115.2603) 84 | # Denver: (39.7621,-104.8759) 85 | # Phoenix: (33.5722,-112.0891) 86 | # Tucson: (32.1558,-110.8777) 87 | # Salt Lake City: (40.7774,-111.9301) 88 | 89 | # TODO Get latitude and longitude values from the user 90 | 91 | def cityreader_stretch(lat1, lon1, lat2, lon2, cities=[]): 92 | # within will hold the cities that fall within the specified region 93 | within = [] 94 | 95 | # Go through each city and check to see if it falls within 96 | # the specified coordinates. 97 | 98 | return within 99 | -------------------------------------------------------------------------------- /small programs/cityreader/test_cityreader.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from cityreader import City, cityreader 3 | 4 | def check_city(inp, exp): 5 | if inp.name != exp.name: 6 | return False 7 | if inp.lat != exp.lat: 8 | return False 9 | if inp.lon != exp.lon: 10 | return False 11 | return True 12 | 13 | class CityreaderTests(unittest.TestCase): 14 | def setUp(self): 15 | self.cities = cityreader() 16 | self.expected = [ 17 | City("Seattle", 47.6217,-122.3238), 18 | City("Richmond", 37.5294,-77.4755), 19 | City("Virginia Beach", 36.7335,-76.0435), 20 | City("Washington", 38.9047,-77.0163), 21 | City("Milwaukee", 43.064,-87.9669), 22 | City("Orlando", 28.4801,-81.3448), 23 | City("Miami", 25.784,-80.2102), 24 | City("Tampa", 27.9937,-82.4454), 25 | City("Jacksonville", 30.3322,-81.6749), 26 | City("Albuquerque", 35.1055,-106.6476), 27 | City("Fort Worth", 32.7813,-97.3466), 28 | City("McAllen", 26.2203,-98.2457), 29 | City("El Paso", 31.8478,-106.431), 30 | City("Dallas", 32.7938,-96.7659), 31 | City("Austin", 30.3038,-97.7545), 32 | City("Houston", 29.7871,-95.3936), 33 | City("San Antonio", 29.4722,-98.5247), 34 | City("New Orleans", 30.0687,-89.9288), 35 | City("Charlotte", 35.208,-80.8308), 36 | City("Raleigh", 35.8323,-78.6441), 37 | City("Omaha", 41.2634,-96.0453), 38 | City("Memphis", 35.1047,-89.9773), 39 | City("Nashville", 36.1714,-86.7844), 40 | City("Buffalo", 42.9016,-78.8487), 41 | City("Queens", 40.7498,-73.7976), 42 | City("New York", 40.6943,-73.9249), 43 | City("Bronx", 40.8501,-73.8662), 44 | City("Brooklyn", 40.6501,-73.9496), 45 | City("Manhattan", 40.7834,-73.9662), 46 | City("Philadelphia", 40.0076,-75.134), 47 | City("Pittsburgh", 40.4396,-79.9763), 48 | City("Sacramento", 38.5666,-121.4683), 49 | City("Riverside", 33.9382,-117.3949), 50 | City("San Francisco", 37.7561,-122.4429), 51 | City("San Diego", 32.8312,-117.1225), 52 | City("San Jose", 37.302,-121.8488), 53 | City("Los Angeles", 34.114,-118.4068), 54 | City("Las Vegas", 36.2288,-115.2603), 55 | City("Denver", 39.7621,-104.8759), 56 | City("Chicago", 41.8373,-87.6861), 57 | City("Atlanta", 33.7627,-84.4231), 58 | City("Indianapolis", 39.7771,-86.1458), 59 | City("Oklahoma City", 35.4677,-97.5138), 60 | City("Phoenix", 33.5722,-112.0891), 61 | City("Tucson", 32.1558,-110.8777), 62 | City("Bridgeport", 41.1909,-73.1958), 63 | City("Hartford", 41.7661,-72.6834), 64 | City("Baltimore", 39.3051,-76.6144), 65 | City("Boston", 42.3189,-71.0838), 66 | City("Cleveland", 41.4766,-81.6805), 67 | City("Columbus", 39.9859,-82.9852), 68 | City("Cincinnati", 39.1412,-84.506), 69 | City("Salt Lake City", 40.7774,-111.9301), 70 | City("Saint Louis", 38.6358,-90.2451), 71 | City("Kansas City", 39.1239,-94.5541), 72 | City("Minneapolis", 44.9635,-93.2679), 73 | City("Detroit", 42.3834,-83.1024), 74 | City("Providence", 41.8229,-71.4186), 75 | City("Louisville", 38.1662,-85.6488), 76 | City("Portland", 45.5372,-122.65) 77 | ] 78 | 79 | def test_cityreader_correctness(self): 80 | self.assertEqual(len(self.cities), 60) 81 | for i in range(len(self.cities)): 82 | self.assertTrue(check_city(self.cities[i], self.expected[i])) 83 | 84 | 85 | if __name__ == '__main__': 86 | unittest.main() -------------------------------------------------------------------------------- /small programs/cityreader/test_stretch.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from cityreader import City, cityreader, cityreader_stretch 3 | 4 | def check_city(inp, exp): 5 | if inp.name != exp.name: 6 | return False 7 | if inp.lat != exp.lat: 8 | return False 9 | if inp.lon != exp.lon: 10 | return False 11 | return True 12 | 13 | class CityreaderTests(unittest.TestCase): 14 | def setUp(self): 15 | self.cities = cityreader() 16 | 17 | def test_cityreader_stretch_correctness(self): 18 | expected = [ 19 | City("Albuquerque", 35.1055,-106.6476), 20 | City("Riverside", 33.9382,-117.3949), 21 | City("San Diego", 32.8312,-117.1225), 22 | City("Los Angeles", 34.114,-118.4068), 23 | City("Las Vegas", 36.2288,-115.2603), 24 | City("Denver", 39.7621,-104.8759), 25 | City("Phoenix", 33.5722,-112.0891), 26 | City("Tucson", 32.1558,-110.8777), 27 | City("Salt Lake City", 40.7774,-111.9301) 28 | ] 29 | 30 | inp = cityreader_stretch(45, -100, 32, -120, self.cities) 31 | 32 | self.assertEqual(len(inp), len(expected)) 33 | 34 | for i in range(len(inp)): 35 | self.assertTrue(check_city(inp[i], expected[i])) 36 | 37 | inp = cityreader_stretch(32, -120, 45, -100, self.cities) 38 | 39 | self.assertEqual(len(inp), len(expected)) 40 | 41 | for i in range(len(inp)): 42 | self.assertTrue(check_city(inp[i], expected[i])) 43 | 44 | expected = [ 45 | City("Richmond", 37.5294,-77.4755), 46 | City("Virginia Beach", 36.7335,-76.0435), 47 | City("Washington", 38.9047,-77.0163), 48 | City("Orlando", 28.4801,-81.3448), 49 | City("Miami", 25.784,-80.2102), 50 | City("Tampa", 27.9937,-82.4454), 51 | City("Jacksonville", 30.3322,-81.6749), 52 | City("Albuquerque", 35.1055,-106.6476), 53 | City("Fort Worth", 32.7813,-97.3466), 54 | City("McAllen", 26.2203,-98.2457), 55 | City("El Paso", 31.8478,-106.431), 56 | City("Dallas", 32.7938,-96.7659), 57 | City("Austin", 30.3038,-97.7545), 58 | City("Houston", 29.7871,-95.3936), 59 | City("San Antonio", 29.4722,-98.5247), 60 | City("New Orleans", 30.0687,-89.9288), 61 | City("Charlotte", 35.208,-80.8308), 62 | City("Raleigh", 35.8323,-78.6441), 63 | City("Memphis", 35.1047,-89.9773), 64 | City("Nashville", 36.1714,-86.7844), 65 | City("Riverside", 33.9382,-117.3949), 66 | City("San Diego", 32.8312,-117.1225), 67 | City("Los Angeles", 34.114,-118.4068), 68 | City("Las Vegas", 36.2288,-115.2603), 69 | City("Denver", 39.7621,-104.8759), 70 | City("Atlanta", 33.7627,-84.4231), 71 | City("Indianapolis", 39.7771,-86.1458), 72 | City("Oklahoma City", 35.4677,-97.5138), 73 | City("Phoenix", 33.5722,-112.0891), 74 | City("Tucson", 32.1558,-110.8777), 75 | City("Baltimore", 39.3051,-76.6144), 76 | City("Columbus", 39.9859,-82.9852), 77 | City("Cincinnati", 39.1412,-84.506), 78 | City("Saint Louis", 38.6358,-90.2451), 79 | City("Kansas City", 39.1239,-94.5541), 80 | City("Louisville", 38.1662,-85.6488) 81 | ] 82 | 83 | inp = cityreader_stretch(40, -50, 12, -120, self.cities) 84 | 85 | for i in range(len(inp)): 86 | self.assertTrue(check_city(inp[i], expected[i])) 87 | 88 | 89 | if __name__ == '__main__': 90 | unittest.main() -------------------------------------------------------------------------------- /small programs/comp/comp.py: -------------------------------------------------------------------------------- 1 | # The following list comprehension exercises will make use of the 2 | # defined Human class. 3 | class Human: 4 | def __init__(self, name, age): 5 | self.name = name 6 | self.age = age 7 | 8 | def __repr__(self): 9 | return f"" 10 | 11 | humans = [ 12 | Human("Alice", 29), 13 | Human("Bob", 32), 14 | Human("Charlie", 37), 15 | Human("Daphne", 30), 16 | Human("Eve", 26), 17 | Human("Frank", 18), 18 | Human("Glenn", 42), 19 | Human("Harrison", 12), 20 | Human("Igon", 41), 21 | Human("David", 31), 22 | ] 23 | 24 | # Write a list comprehension that creates a list of names of everyone 25 | # whose name starts with 'D': 26 | print("Starts with D:") 27 | a = [h.name for h in humans if h.name.startswith("D")] 28 | print(a) 29 | 30 | # Write a list comprehension that creates a list of names of everyone 31 | # whose name ends in "e". 32 | print("Ends with e:") 33 | b = [h.name for h in humans if h.name.endswith("e")] 34 | print(b) 35 | 36 | # Write a list comprehension that creates a list of names of everyone 37 | # whose name starts with any letter between 'C' and 'G' inclusive. 38 | print("Starts between C and G, inclusive:") 39 | c = [h.name for h in humans if h.name[0] >= "C" and h.name[0] <= "G"] 40 | print(c) 41 | 42 | # Write a list comprehension that creates a list of all the ages plus 10. 43 | print("Ages plus 10:") 44 | d = [h.age + 10 for h in humans] 45 | print(d) 46 | 47 | # Write a list comprehension that creates a list of strings which are the name 48 | # joined to the age with a hyphen, for example "David-31", for all humans. 49 | print("Name hyphen age:") 50 | e = [h.name + "-" + str(h.age) for h in humans] 51 | print(e) 52 | 53 | # Write a list comprehension that creates a list of tuples containing name and 54 | # age, for example ("David", 31), for everyone between the ages of 27 and 32, 55 | # inclusive. 56 | print("Names and ages between 27 and 32:") 57 | f = [(h.name, h.age) for h in humans if h.age >= 27 and h.age <= 32] 58 | print(f) 59 | 60 | # Write a list comprehension that creates a list of new Humans like the old 61 | # list, except with all the names uppercase and the ages with 5 added to them. 62 | # The "humans" list should be unmodified. 63 | # print(humans) 64 | print("All names uppercase:") 65 | hums = humans 66 | for hum in hums: 67 | hum.name = hum.name.upper() 68 | hum.age = hum.age +5 69 | g = [hm for hm in hums] 70 | print(g) 71 | 72 | # Write a list comprehension that contains the square root of all the ages. 73 | print("Square root of ages:") 74 | import math 75 | h = [pow(h.age, 2) for h in humans] 76 | print(h) 77 | -------------------------------------------------------------------------------- /small programs/comp/test_comp.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from comp import * 3 | 4 | def compare_humans(inp, exp): 5 | if len(inp) != len(exp): 6 | return False 7 | for i in range(len(inp)): 8 | if inp[i].name != exp[i].name: 9 | return False 10 | if inp[i].age != exp[i].age: 11 | return False 12 | return True 13 | 14 | class CompTests(unittest.TestCase): 15 | def test_starts_with_D(self): 16 | self.assertEqual(a, ['Daphne', 'David']) 17 | 18 | def test_ends_with_e(self): 19 | self.assertEqual(b, ['Alice', 'Charlie', 'Daphne', 'Eve']) 20 | 21 | def test_between_C_and_G(self): 22 | self.assertEqual(c, ['Charlie', 'Daphne', 'Eve', 'Frank', 'Glenn', 'David']) 23 | 24 | def test_ages_plus_10(self): 25 | self.assertEqual(d, [39, 42, 47, 40, 36, 28, 52, 22, 51, 41]) 26 | 27 | def test_name_hyphen_age(self): 28 | self.assertEqual(e, ['Alice-29', 'Bob-32', 'Charlie-37', 'Daphne-30', 'Eve-26', 'Frank-18', 'Glenn-42', 'Harrison-12', 'Igon-41', 'David-31']) 29 | 30 | def test_names_ages_between_27_and_32(self): 31 | self.assertEqual(f, [('Alice', 29), ('Bob', 32), ('Daphne', 30), ('David', 31)]) 32 | 33 | def test_all_names_uppercase(self): 34 | expected = [Human("ALICE", 34), Human("BOB", 37), Human("CHARLIE", 42), Human("DAPHNE", 35), Human("EVE", 31), Human("FRANK", 23), Human("GLENN", 47), Human("HARRISON", 17), Human("IGON", 46), Human("DAVID", 36)] 35 | self.assertTrue(compare_humans(g, expected)) 36 | 37 | def test_square_root_of_ages(self): 38 | self.assertEqual(h, [5.385164807134504, 5.656854249492381, 6.082762530298219, 5.477225575051661, 5.0990195135927845, 4.242640687119285, 6.48074069840786, 3.4641016151377544, 6.4031242374328485, 5.5677643628300215]) 39 | 40 | 41 | if __name__ == '__main__': 42 | unittest.main() 43 | -------------------------------------------------------------------------------- /small programs/oop/oop1.py: -------------------------------------------------------------------------------- 1 | # Write classes for the following class hierarchy: 2 | # 3 | # [Vehicle]->[FlightVehicle]->[Starship] 4 | # | | 5 | # v v 6 | # [GroundVehicle] [Airplane] 7 | # | | 8 | # v v 9 | # [Car] [Motorcycle] 10 | # 11 | # Each class can simply "pass" for its body. The exercise is about setting up 12 | # the hierarchy. 13 | # 14 | # e.g. 15 | # 16 | # class Whatever: 17 | # pass 18 | # 19 | # Put a comment noting which class is the base class 20 | 21 | #base class 22 | class Vehicle: 23 | pass 24 | 25 | class GroundVehicle(Vehicle): 26 | pass 27 | 28 | class Car(GroundVehicle): 29 | pass 30 | 31 | class Motorcycle(Car): 32 | pass 33 | 34 | class FlightVehicle(Vehicle): 35 | pass 36 | 37 | class Airplane(FlightVehicle): 38 | pass 39 | 40 | class Starship(FlightVehicle): 41 | pass 42 | -------------------------------------------------------------------------------- /small programs/oop/oop2.py: -------------------------------------------------------------------------------- 1 | # To the GroundVehicle class, add method drive() that returns "vroooom". 2 | # 3 | # Also change it so the num_wheels defaults to 4 if not specified when the 4 | # object is constructed. 5 | 6 | class GroundVehicle(): 7 | def __init__(self, num_wheels = 4): 8 | self.num_wheels = num_wheels 9 | 10 | def drive(self): 11 | return "vroooom" 12 | 13 | def __str__(self): 14 | return "num_wheels:" + str(self.num_wheels) + " ground vehicle" 15 | 16 | 17 | class Motorcycle(GroundVehicle): 18 | def __init__(self): 19 | super().__init__(2) 20 | 21 | def __str__(self): 22 | return "num_wheels: " + str(self.num_wheels) + " motorcycle" 23 | 24 | def drive(self): 25 | return "BRAAAP!!" 26 | 27 | 28 | # Subclass Motorcycle from GroundVehicle. 29 | # 30 | # Make it so when you instantiate a Motorcycle, it automatically sets the number 31 | # of wheels to 2 by passing that to the constructor of its superclass. 32 | # 33 | # Override the drive() method in Motorcycle so that it returns "BRAAAP!!" 34 | 35 | # TODO 36 | 37 | vehicles = [ 38 | GroundVehicle(), 39 | GroundVehicle(), 40 | Motorcycle(), 41 | GroundVehicle(), 42 | Motorcycle(), 43 | ] 44 | 45 | # Go through the vehicles list and print the result of calling drive() on each. 46 | 47 | # TODO 48 | 49 | for vehicle in vehicles: 50 | print(vehicle.drive()) 51 | -------------------------------------------------------------------------------- /small programs/oop/test_oop1.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from oop1 import * 3 | 4 | class Oop1Tests(unittest.TestCase): 5 | def setUp(self): 6 | self.vehicle = Vehicle() 7 | self.flight_vehicle = FlightVehicle() 8 | self.ground_vehicle = GroundVehicle() 9 | self.car = Car() 10 | self.motorcycle = Motorcycle() 11 | self.starship = Starship() 12 | self.airplane = Airplane() 13 | 14 | def test_flight_vehicle(self): 15 | self.assertTrue(isinstance(self.flight_vehicle, FlightVehicle)) 16 | self.assertTrue(isinstance(self.flight_vehicle, Vehicle)) 17 | 18 | def test_ground_vehicle(self): 19 | self.assertTrue(isinstance(self.ground_vehicle, GroundVehicle)) 20 | self.assertTrue(isinstance(self.ground_vehicle, Vehicle)) 21 | 22 | def test_starship(self): 23 | self.assertTrue(isinstance(self.starship, Starship)) 24 | self.assertTrue(isinstance(self.starship, FlightVehicle)) 25 | self.assertTrue(isinstance(self.starship, Vehicle)) 26 | 27 | def test_airplane(self): 28 | self.assertTrue(isinstance(self.airplane, Airplane)) 29 | self.assertTrue(isinstance(self.airplane, FlightVehicle)) 30 | self.assertTrue(isinstance(self.starship, Vehicle)) 31 | 32 | def test_car(self): 33 | self.assertTrue(isinstance(self.car, Car)) 34 | self.assertTrue(isinstance(self.car, GroundVehicle)) 35 | self.assertTrue(isinstance(self.car, Vehicle)) 36 | 37 | def test_motocycle(self): 38 | self.assertTrue(isinstance(self.motorcycle, Motorcycle)) 39 | self.assertTrue(isinstance(self.motorcycle, GroundVehicle)) 40 | self.assertTrue(isinstance(self.motorcycle, Vehicle)) 41 | 42 | 43 | if __name__ == '__main__': 44 | unittest.main() -------------------------------------------------------------------------------- /small programs/oop/test_oop2.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from oop2 import * 3 | 4 | class Oop2Tests(unittest.TestCase): 5 | def setUp(self): 6 | self.ground_vehicle = GroundVehicle() 7 | self.motorcycle = Motorcycle() 8 | 9 | def test_motorcycle_inheritance(self): 10 | self.assertTrue(isinstance(self.motorcycle, GroundVehicle)) 11 | 12 | def test_ground_vehicle_num_wheels(self): 13 | self.assertEqual(self.ground_vehicle.num_wheels, 4) 14 | 15 | def test_motocycle_num_wheels(self): 16 | self.assertEqual(self.motorcycle.num_wheels, 2) 17 | 18 | def test_ground_vehicle_drive(self): 19 | self.assertEqual(self.ground_vehicle.drive(), "vroooom") 20 | 21 | def test_motorcyle_drive(self): 22 | self.assertEqual(self.motorcycle.drive(), "BRAAAP!!") 23 | 24 | 25 | if __name__ == '__main__': 26 | unittest.main() --------------------------------------------------------------------------------