Skip to content

Assignment1 #926

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[report]
omit =
*/tests/*
*/python?.?/*
*/site-packages/nose/*
*__init__*
529 changes: 105 additions & 424 deletions README.md

Large diffs are not rendered by default.

424 changes: 424 additions & 0 deletions README_original.md

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion algorithms/maths/find_order_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def find_order(a, n):
"""
Find order for positive integer n and given integer a that satisfies gcd(a, n) = 1.
"""

if (a == 1) & (n == 1):
# Exception Handeling : 1 is the order of of 1
return 1
Expand All @@ -24,4 +25,4 @@ def find_order(a, n):
for i in range(1, n):
if pow(a, i) % n == 1:
return i
return -1
return -1
1 change: 0 additions & 1 deletion algorithms/maths/prime_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ def prime_check(n):
"""Return True if n is a prime number
Else return False.
"""

if n <= 1:
return False
if n == 2 or n == 3:
Expand Down
28 changes: 28 additions & 0 deletions algorithms/maths/pythagoras.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
Given the lengths of two of the three sides of a right angled triangle, this function returns the
length of the third side.
"""
branch_coverage = {
"branch_1": False,
"branch_2": False,
"branch_3": False,
"branch_4": False,
#"branch_5": False
}

def pythagoras(opposite, adjacent, hypotenuse):
"""
Expand All @@ -10,11 +17,32 @@ def pythagoras(opposite, adjacent, hypotenuse):
"""
try:
if opposite == str("?"):
branch_coverage["branch_1"] = True
print("branch_1")
return ("Opposite = " + str(((hypotenuse**2) - (adjacent**2))**0.5))
if adjacent == str("?"):
branch_coverage["branch_2"] = True
print("branch_2")
return ("Adjacent = " + str(((hypotenuse**2) - (opposite**2))**0.5))
if hypotenuse == str("?"):
branch_coverage["branch_3"] = True
print("branch_3")
return ("Hypotenuse = " + str(((opposite**2) + (adjacent**2))**0.5))
branch_coverage["branch_4"] = True
print("branch_4")
return "You already know the answer!"
except:
# branch_coverage["branch_5"] = True
# print("branch_5")
raise ValueError("invalid argument(s) were given.")

def print_coverage():
for branch, hit in branch_coverage.items():
print(f"{branch} was {'hit' if hit else 'not hit'}")

print_coverage()

# total = len(branch_coverage)
# reached_branches = sum(branch_coverage.values())
# percentage = (reached_branches/total)*100
# print_coverage()
3 changes: 2 additions & 1 deletion algorithms/search/interpolation_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ def interpolation_search(array: List[int], search_key: int) -> int:
# if search_key is smaller, search_key is in lower part
else:
high = pos - 1

return -1



if __name__ == "__main__":
Expand Down
17 changes: 17 additions & 0 deletions algorithms/sort/insertion_sort.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,42 @@
branch_coverage = {
"simulation": False,
"for": False,
"while": False,
"simulation-nested": False,
}

def insertion_sort(arr, simulation=False):
""" Insertion Sort
Complexity: O(n^2)
"""

iteration = 0
if simulation:
branch_coverage["simulation"] = True
print("iteration",iteration,":",*arr)

for i in range(len(arr)):
branch_coverage["for"] = True
cursor = arr[i]
pos = i

while pos > 0 and arr[pos - 1] > cursor:
branch_coverage["while"] = True
# Swap the number down the list
arr[pos] = arr[pos - 1]
pos = pos - 1
# Break and do the final swap
arr[pos] = cursor

if simulation:
branch_coverage["simulation-nested"] = True
iteration = iteration + 1
print("iteration",iteration,":",*arr)

return arr

def print_coverage():
print("branch coverage for `insertion_sort`:")
for branch, hit in branch_coverage.items():
print(f"{branch} was {'hit' if hit else 'not hit'}")

15 changes: 15 additions & 0 deletions algorithms/unix/path/simplify_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,30 @@
Reference: https://leetcode.com/problems/simplify-path/description/
"""

branch_coverage = {
"for": False,
"if": False,
"elif": False,
}

import os
def simplify_path_v1(path):
return os.path.abspath(path)

def simplify_path_v2(path):
stack, tokens = [], path.split("/")
for token in tokens:
branch_coverage["for"] = True
if token == ".." and stack:
branch_coverage["if"] = True
stack.pop()
elif token != ".." and token != "." and token:
branch_coverage["elif"] = True
stack.append(token)

return "/" + "/".join(stack)

def print_coverage():
print("branch coverage for `simplify_path_v2`:")
for branch, hit in branch_coverage.items():
print(f"{branch} was {'hit' if hit else 'not hit'}")
4 changes: 4 additions & 0 deletions branch-coverage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import subprocess

subprocess.run(["coverage", "run", "--branch", "-m", "pytest", "tests"])
subprocess.run(["coverage", "report"])
Binary file added image-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion tests/test_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
missing_ranges,
move_zeros,
plus_one_v1, plus_one_v2, plus_one_v3,
remove_duplicates
remove_duplicates,
rotate_v1, rotate_v2, rotate_v3,
summarize_ranges,
three_sum,
Expand Down
61 changes: 52 additions & 9 deletions tests/test_maths.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from algorithms.maths.prime_check import prime_check, print_coverage
import unittest

from algorithms.maths import (
power, power_recur,
int_to_base, base_to_int,
Expand Down Expand Up @@ -276,17 +279,45 @@ class TestPrimeTest(unittest.TestCase):
Arguments:
unittest {[type]} -- [description]
"""


def test_prime_test(self):
def test_prime_numbers(self):
"""
checks all prime numbers between 2 up to 100.
Between 2 up to 100 exists 25 prime numbers!
Checks specific prime numbers between 2 up to 100.
"""
counter = 0
for i in range(2, 101):
if prime_check(i):
counter += 1
self.assertEqual(25, counter)
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
for prime in primes:
with self.subTest(n=prime):
self.assertTrue(prime_check(prime), f"{prime} should be prime")

def test_non_prime_numbers(self):
"""
Checks specific non-prime numbers between 2 up to 100.
"""
non_primes = [4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28, 30, 32, 33, 34, 35, 36, 38, 39, 40, 42, 44, 45, 46, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 60, 62, 63, 64, 65, 66, 68, 69, 70, 72, 74, 75, 76, 77, 78, 80, 81, 82, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, 98, 99, 100]
for non_prime in non_primes:
with self.subTest(n=non_prime):
self.assertFalse(prime_check(non_prime), f"{non_prime} should not be prime")

def test_prime_check_coverage(self):
"""
Additional checks to cover all branches in prime_check function.
"""
self.assertFalse(prime_check(-1), "-1 should not be prime") # Branch 1
self.assertFalse(prime_check(0), "0 should not be prime") # Branch 1
self.assertFalse(prime_check(1), "1 should not be prime") # Branch 1
self.assertTrue(prime_check(2), "2 should be prime") # Branch 2
self.assertTrue(prime_check(3), "3 should be prime") # Branch 2
self.assertFalse(prime_check(4), "4 should not be prime") # Branch 3
self.assertFalse(prime_check(9), "9 should not be prime") # Branch 3
self.assertFalse(prime_check(15), "15 should not be prime") # Branch 3, 4, 5
self.assertTrue(prime_check(5), "5 should be prime") # Branch 4
self.assertTrue(prime_check(7), "7 should be prime") # Branch 4
self.assertFalse(prime_check(25), "25 should not be prime") # Branch 5
self.assertFalse(prime_check(49), "49 should not be prime") # Branch 5
self.assertFalse(prime_check(50), "50 should not be prime") # Branch 3
self.assertTrue(prime_check(97), "97 should be prime") # Branch 4



class TestPythagoras(unittest.TestCase):
Expand All @@ -301,6 +332,16 @@ def test_pythagoras(self):
self.assertEqual("Hypotenuse = 3.605551275463989",
pythagoras(3, 2, "?"))

def test_opposite_calculation(self):
result = pythagoras("?", 4, 5)
expected = "Opposite = 3.0"
self.assertEqual(result, expected)

def test_adjacent_calculation(self):
result = pythagoras(3, "?", 5)
expected = "Adjacent = 4.0"
self.assertEqual(result, expected)


class TestRabinMiller(unittest.TestCase):
"""[summary]
Expand Down Expand Up @@ -434,10 +475,12 @@ class TestFindOrder(unittest.TestCase):
"""

def test_find_order_simple(self):
self.assertEqual(1, find_order(1, 1))
self.assertEqual(1, find_order(1, 1)) # Should hit branch_1
self.assertEqual(6, find_order(3, 7))
self.assertEqual(-1, find_order(128, 256))
self.assertEqual(352, find_order(3, 353))
self.assertEqual(-1, find_order(10, 20)) # Should hit branches 2, 3, 5



class TestKrishnamurthyNumber(unittest.TestCase):
Expand Down
2 changes: 2 additions & 0 deletions tests/test_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,14 @@ def test_next_greatest_letter(self):

def test_interpolation_search(self):
array = [0, 3, 5, 5, 9, 12, 12, 15, 16, 19, 20]

self.assertEqual(1, interpolation_search(array, 3))
self.assertEqual(2, interpolation_search(array, 5))
self.assertEqual(6, interpolation_search(array, 12))
self.assertEqual(-1, interpolation_search(array, 22))
self.assertEqual(-1, interpolation_search(array, -10))
self.assertEqual(10, interpolation_search(array, 20))



if __name__ == '__main__':
Expand Down
1 change: 1 addition & 0 deletions tests/test_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ class TestFirstUniqueChar(unittest.TestCase):
def test_first_unique_char(self):
self.assertEqual(0, first_unique_char("leetcode"))
self.assertEqual(2, first_unique_char("loveleetcode"))
self.assertEqual(-1, first_unique_char("aabb"))


class TestRepeatSubstring(unittest.TestCase):
Expand Down
26 changes: 24 additions & 2 deletions tests/test_unix.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import os
import unittest

from algorithms.unix import (
print_coverage
)

class TestUnixPath(unittest.TestCase):
def test_join_with_slash(self):
Expand Down Expand Up @@ -42,7 +45,26 @@ def test_split(self):
self.assertEqual("test.py", expect_result[1])

def test_simplify_path(self):
self.assertEqual("/", simplify_path_v1("/../"))
self.assertEqual("/home/foo", simplify_path_v1("/home//foo/"))
root = None
pathsep = None
drive = None
if os.name == 'nt':
root = "" # Assumed to be ran on the C drive
pathsep = "\\"
drive = "C:\\"
elif os.name == 'posix':
root = "/"
pathsep = "/"
drive = ""

self.assertEqual(drive + root, simplify_path_v1("/../"))
self.assertEqual(drive + root + pathsep.join(["home", "foo"]), simplify_path_v1("/home//foo/"))

self.assertEqual("/", simplify_path_v2("."))
self.assertEqual("/", simplify_path_v2("/../"))
self.assertEqual("/home/foo", simplify_path_v2("/home//foo/"))
self.assertEqual("/", simplify_path_v2(""))
self.assertEqual("/", simplify_path_v2("/home/../"))

print_coverage()