From 19692369fce154c4e70fc8da5fee651564ae0362 Mon Sep 17 00:00:00 2001 From: Dan Goldsmith Date: Mon, 29 Mar 2021 16:41:58 +0100 Subject: [PATCH] Basic Algs update --- README.md | 36 +++++++++++ REQUIREMENTS.txt | 1 + basicAlgs.py | 152 +++++++++++++++++++++++++++++++++++++++++++++++ test_algs.py | 129 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 318 insertions(+) create mode 100644 README.md create mode 100644 REQUIREMENTS.txt create mode 100644 basicAlgs.py create mode 100644 test_algs.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..b1b947b --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +# Programming Test for 4062 v4 + +Your task is to fix the code. + +You will need to submit: + + - A Screenshot of the final code output + - A Screenshot of the test cases passing + - A copy of the changes you have made to the code. + + +## Requirements + +You will need to install pytest to run the unittests + +``` +$ pip install pytest +``` + +## Running the tests + +To run the tests use + +``` +pytest -v +``` + +## Runing the Code + +You can run the code with + +``` +python3 basicAlgs.py +``` + +You will need to include the output of the program in the report. diff --git a/REQUIREMENTS.txt b/REQUIREMENTS.txt new file mode 100644 index 0000000..e079f8a --- /dev/null +++ b/REQUIREMENTS.txt @@ -0,0 +1 @@ +pytest diff --git a/basicAlgs.py b/basicAlgs.py new file mode 100644 index 0000000..ed8b40a --- /dev/null +++ b/basicAlgs.py @@ -0,0 +1,152 @@ +""" +Python code to do sometihng that we can easily break + +Most of it will be classic Algorithms. +""" + +import logging + +def bubblesort(theList): + """ + + The Classic Bubble sort. + + Iterate through the list, looking at each pair of items. + If the left hand side of the pair is larger than the right hand side + swap them. + + This means that after the first iteration, the largest item is at + the end of the list. + + We then repeat the process, shifting the second largest item to the correct place. + Then continue till all items are sorted. + + See: + + https://www.tutorialspoint.com/data_structures_algorithms/bubble_sort_algorithm.htm + + + @param theList: Initial List (or iterable) + @return: A sorted version of the list + + """ + #Outer Loop + for outer in range(len(theList)): + # Inner Loop, + for inner in range(len(theList)-1): + #Get the values + leftItem = theList[inner] + rightItem = theList[inner+1] + + #Do the Comparison + if leftItem > rightItem: + #Swap + theList[inner] = rightItem + theList[inner] = leftItem + + logging.debug("Iteration {0} List is {1}".format(outer, theList)) + + return theList + + +def binarySearch(theList, value): + """ + The Classic Binary Search Algorithm + + This will take a *SORTED* list, and search it for a given + value. + + We use an iterative approach here, because recursive might be + confusing (even though its actually a lot easier to code). + + @param theList: Sorted list to search + @param value: Value to search for + @return Index of item in the List + """ + + bottom = 0 + top = len(theList) + #while True: + #for x in range(5): + while (top - bottom) >= 1: + # Find the Middle of the Array + middle = bottom + (top - bottom) // 2 + #middle = bottom + top // 2 + logging.debug("Binary Search Bottom %d Top %d Middle (%d)", bottom, top, middle) + + # Get the item at this index + item = theList[middle] + logging.debug("--> Item is %d", item) + logging.debug("--> Searching Array {0}".format(theList[bottom:top])) + if item == value: + #If we have found the Item + return middle + elif item > value: + # The Value at the Midpoint is Greater than our value + # We need to look in the bottom half + logging.debug("Use Bottom Half") + top = middle# + 1 + elif item < value: + # The Value at the Midpoint is Less than our Value + # We need to look in the Top half + logging.debug("Use Top Half") + bottom = middle + 1 + + + +def searcher(theList, theValue): + """ + Take a user specified list and search it for + a value + + @param theList: List of items to check + @param theValue: Value to look for + + @return: Index of item if it exists + """ + theList = bubblesort(theList) + hasItem = binarySearch(theList, theValue) + return hasItem + + +def convertValues(rawValues, rawSearch): + """ + Convert text based user input into integer arrays + and values + + @param rawValues: A user supplied comma sepeated string + @param rawSearch: User supplied text integer + + @return list, value converted to integers + """ + + #And process into numbers + values = [int(x) for x in rawValues.split(",")] + logging.debug("Values are {0}".format(values)) + + searchValue = int(rawSearch) + logging.debug("Searching for {0}".format(searchValue)) + + return values, searchValue + + +if __name__ == "__main__": + """ + Main Function + """ + #You can change this to debug to see the debugging messages + logging.basicConfig(level=logging.INFO) + #logging.basicConfig(level=logging.DEBUG) + + print("==== COPY THE BELOW INTO THE REPORT =====") + print("---- Sanity Check 1 -----") + values = [1,2,3,4,5,6,7,8,9,10] + out = searcher(values, 3) + print(out) + + + print("---- Sanity Check 2-----") + values = [7,6,5,4,3,2,1] + out = searcher(values, 3) + print(out) + diff --git a/test_algs.py b/test_algs.py new file mode 100644 index 0000000..330e69e --- /dev/null +++ b/test_algs.py @@ -0,0 +1,129 @@ +""" +Test Cases for the Program +""" + +import unittest + +import basicAlgs + +class IntergrationTest(unittest.TestCase): + """ + Test the main program runs correctly + """ + + def test_search_one(self): + """ + Test searching algorithm with sorted string + """ + values = [1,2,3,4,5,6] + out = basicAlgs.searcher(values, 3) + self.assertEqual(out, 2) + + def test_search_two(self): + """ + Test searching algorithm with even numbers + """ + values = [1,2,4,8,16,32] + out = basicAlgs.searcher(values, 8) + self.assertEqual(out, 3) + + def test_search_three(self): + """ + Test search with unsorted string + """ + values = [7,6,5,4,3,2,1] + out = basicAlgs.searcher(values, 3) + self.assertEqual(out, 2) + + def text_search_text(self): + """ + Test our conversion function + """ + textVals = "1,2,3,4,5" + textNum = 3 + + values, num = basicAlgs.convertValues(textVals, textNum) + self.assertEqual(values, [1,2,3,4,5]) + self.assertEqual(num, 3) + + +class TestAlgorithms(unittest.TestCase): + """ + Test the base algorithms work correctly + """ + + def test_Bubble(self): + """ + Test our bubble sort function + """ + + theArray = [5,7,4,6,2,9,1] + out = basicAlgs.bubblesort(theArray) + self.assertEqual(out, [1,2,4,5,6,7,9], "Items not sorted correctly") + + + def test_BubbleOrder(self): + """ + Does our bubble sort work if + everything is in order + """ + + theArray = [1,2,3,4,5,6,7] + out = basicAlgs.bubblesort(theArray) + self.assertEqual(out, [1,2,3,4,5,6,7], "Array not sorted correctly") + + + def test_Binsearch(self): + """ + Test binary search + """ + theArray = [1,2,3,4,5,6] + + out = basicAlgs.binarySearch(theArray, 4) + self.assertEqual(out, 3, "Value not found in Array") + + def test_Binsearch_Extremes(self): + """ + Test binary search can find items at + the extremes of the array + """ + + theArray = [1,2,3,4,5,6,7,8] + + out = basicAlgs.binarySearch(theArray, 1) + self.assertEqual(out, 0, "Extreme value not found") + + out = basicAlgs.binarySearch(theArray, 8) + self.assertEqual(out, 7, "Extreme value not found") + + + def test_Binsearch_NoVal(self): + """ + Test binary search when the value is not in the array + """ + + theArray = [1,2,3,5,6,7] + out = basicAlgs.binarySearch(theArray, 4) + self.assertFalse(out, "Array finds value when none exists") + + + + def test_binSerarch_Odd(self): + """ + Test the binary search when we have an Odd number of items + """ + theArray = [1,2,3,4,5,6,7] + + for idx, value in enumerate(theArray): + out = basicAlgs.binarySearch(theArray, value) + self.assertEqual(out, idx, "Test Fails with odd sized array") + + def test_binSerarch_Even(self): + """ + Test the binary search when we have an even number of items + """ + theArray = [1,2,3,4,5,6,7,8] + + for idx, value in enumerate(theArray): + out = basicAlgs.binarySearch(theArray, value) + self.assertEqual(out, idx, "Test Fails with Even sized array")