Skip to content

Instantly share code, notes, and snippets.

@Samyak2
Last active December 9, 2021 07:56
Show Gist options
  • Save Samyak2/20eaef27510506fc74408f59cdcb3a2c to your computer and use it in GitHub Desktop.
Save Samyak2/20eaef27510506fc74408f59cdcb3a2c to your computer and use it in GitHub Desktop.
Random test case generator and tester for intal in C
# this is a testing file for intal (integer of arbitrary length) in C, to be used with the python file
# Steps to use
# 1. Compile with the main file (which is here - https://gist.github.com/Samyak2/d0c2552b11581f59091f9f377bbc65f0)
# 1.1 Make sure the executable is named `intal` (using `-o intal` during compiling)
# 2. Make sure python version is >=3.6 and scipy is installed
# 3. Run this script
# excuse the bad code, it was only intended to work
# Here is another version to test the time complexity - https://gist.github.com/Samyak2/a2975ec738e76dd7ead1147db3c0ef93
# Author: Samyak S Sarnayak
import sys
import subprocess
import random
import operator
import math
import scipy.special
def fibonacci(n):
a = 0
b = 1
if n == 0:
return a
if n == 1:
return b
for _ in range(2, n+1):
c = a + b
a = b
b = c
return b
def coin_row_problem(arr, s):
n = len(arr)
if n == 0:
return 0
prev = 0
cur = arr[0]
for i in range(1, n):
next_ = max(prev+arr[i], cur)
prev = cur
cur = next_
return cur
max_ = 10**1000
def test_intal_outs_binary(operation, name, cases=100, max1=max_//2, max2=max_//2):
passed = 0
skipped = 0
total_time = 0.0
max_time = 0.0
for _ in range(cases):
a = random.randrange(0, max1)
b = random.randrange(0, max2)
try:
expected_res = operation(a, b)
if expected_res > max_:
# print(f"Skipped a test case due to result being huge. {a} {name} {b} = {expected_res}")
skipped += 1
continue
p = subprocess.run(["./intal", name], check=True,
input=f"{a}\n{b}\n",
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
encoding="ascii")
# res = int(p.stdout.strip())
res, time = p.stdout.strip().split()
res = res.strip() # int(res)
expected_res = str(expected_res)
time = float(time)
if time > max_time:
max_time = time
total_time += time
if res == expected_res:
passed += 1
else:
print(f"Test failed: {a} {name} {b} = {expected_res} != {res}", file=sys.stderr)
except subprocess.CalledProcessError as e:
print(f"Test failed: for a = {a}, b = {b}. Error: {e}", file=sys.stderr)
except OverflowError as e:
print(f"Test failed due to overflow {a} {name} {b}", file=sys.stderr)
except ValueError as e:
print(f"Test failed due to invalid output: {a} {name} {b} = {expected_res}. Error: {e}", file=sys.stderr)
avg_time = (total_time*1000)/passed if passed > 0 else "N/A"
print(f"{passed} tests passed, {skipped} tests skipped out of {cases} for {name}. Average time taken: {avg_time}ms. Maximum time: {max_time*1000}ms")
def test_intal_outs_unary(operation, name, cases=100, max1=100):
passed = 0
skipped = 0
total_time = 0.0
max_time = 0.0
for _ in range(cases):
a = random.randrange(0, max1)
try:
expected_res = operation(a)
if expected_res > max_:
# print(f"Skipped a test case due to result being huge. {name} {a} = {expected_res}")
skipped += 1
continue
p = subprocess.run(["./intal", name], check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
input=f"{a}\n",
encoding="ascii")
# res = int(p.stdout.strip())
res, time = p.stdout.strip().split()
res = res.strip() # int(res)
expected_res = str(expected_res)
time = float(time)
if time > max_time:
max_time = time
total_time += time
if res == expected_res:
passed += 1
else:
print(f"Test failed: {name} {a} = {expected_res} != {res}", file=sys.stderr)
except subprocess.CalledProcessError as e:
print(f"Test failed: for a = {a}. Error: {e}", file=sys.stderr)
except OverflowError as e:
print(f"Test failed due to overflow {name} {a}", file=sys.stderr)
except ValueError as e:
print(f"Test failed due to invalid output: {name} {a} = {expected_res}. Error: {e}", file=sys.stderr)
avg_time = (total_time*1000)/passed if passed > 0 else "N/A"
print(f"{passed} tests passed, {skipped} tests skipped out of {cases} for {name}. Average time taken: {avg_time}ms. Maximum time: {max_time*1000}ms")
def test_intal_outs_array(operation, name, extra_inp=False, extra_inp_from_arr=False, cases=100, arraylength=50, max1=max_, sort=False,
check_sort=False):
passed = 0
skipped = 0
total_time = 0.0
max_time = 0.0
for __ in range(cases):
arr = [random.randrange(0, max1) for _ in range(arraylength)]
if sort:
arr.sort()
if extra_inp:
if extra_inp_from_arr:
s = random.choice(arr)
else:
s = random.randrange(0, max1)
else:
s = None
try:
expected_res = operation(arr, s)
if not check_sort:
if expected_res > max_:
skipped += 1
continue
p = subprocess.run(["./intal", "array", name], check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
input="{}\n{}\n".format(arraylength, '\n'.join(map(str, arr if s is None else arr+[s]))),
encoding="ascii")
# res = int(p.stdout.strip())
if not check_sort:
res, time = p.stdout.strip().split()
res = res.strip() # int(res)
expected_res = str(expected_res)
else:
res = p.stdout.strip().split()
time = res[-1]
res = res[:-1]
res = [str(res_).strip() for res_ in res]
expected_res = [str(res_) for res_ in expected_res]
time = float(time)
if time > max_time:
max_time = time
total_time += time
if res == expected_res:
passed += 1
else:
print(f"Test failed: {name} {[len(str(a)) for a in arr]} = {expected_res} != {res}", file=sys.stderr)
except subprocess.CalledProcessError as e:
print(f"Test failed: for a = {[len(str(a)) for a in arr]}. Error: {e}", file=sys.stderr)
except OverflowError as e:
print(f"Test failed due to overflow {name} {[len(str(a)) for a in arr]}", file=sys.stderr)
except ValueError as e:
print(f"Test failed due to invalid output: {name} {[len(str(a)) for a in arr]} = {expected_res}. Error: {e}", file=sys.stderr)
avg_time = (total_time*1000)/passed if passed > 0 else "N/A"
print(f"{passed} tests passed, {skipped} tests skipped out of {cases} for {name}. Average time taken: {avg_time}ms. Maximum time: {max_time*1000}ms")
# this feature was implemented by Rehan in his fork. Source: https://gist.github.com/rehanvipin/2bcbe40fb9e25b44c3439f9855df98fb
all_tests = ["add", "diff", "multiply", "mod", "bincoeff", "gcd", "pow", "fibo", "fact", "min", "max", "search", "binsearch", "sort", "coinrow"]
print("Which functions do you want to test?")
for index, _test in enumerate(all_tests):
print(index, _test)
print("Enter your choices, index numbers, separated by a comma, enter 12345 to test them all")
choices = list(map(int, input().split(",")))
use_all = False
if 12345 in choices:
use_all = True
if 0 in choices or use_all:
test_intal_outs_binary(operator.add, "add")
if 1 in choices or use_all:
test_intal_outs_binary(lambda a, b: operator.abs(operator.sub(a, b)), "diff")
if 2 in choices or use_all:
test_intal_outs_binary(operator.mul, "multiply", max1=10**100, max2=10**10)
if 3 in choices or use_all:
test_intal_outs_binary(operator.mod, "mod")
if 4 in choices or use_all:
test_intal_outs_binary(lambda n, k: scipy.special.comb(n, k, exact=True), "bincoeff",
max1=1000,
max2=1000)
if 5 in choices or use_all:
test_intal_outs_binary(math.gcd, "gcd")
if 6 in choices or use_all:
test_intal_outs_binary(operator.pow, "pow", max1=10**3, max2=10**2)
if 7 in choices or use_all:
test_intal_outs_unary(fibonacci, "fibo")
if 8 in choices or use_all:
test_intal_outs_unary(math.factorial, "fact")
if 9 in choices or use_all:
test_intal_outs_array(lambda arr, s: min(enumerate(arr), key=lambda p: p[1])[0], "min")
if 10 in choices or use_all:
test_intal_outs_array(lambda arr, s: max(enumerate(arr), key=lambda p: p[1])[0], "max")
if 11 in choices or use_all:
test_intal_outs_array(lambda arr, s: arr.index(s) if s in arr else -1, "search", extra_inp=True)
test_intal_outs_array(lambda arr, s: arr.index(s) if s in arr else -1, "search", extra_inp=True, extra_inp_from_arr=True)
if 12 in choices or use_all:
test_intal_outs_array(lambda arr, s: arr.index(s) if s in arr else -1, "binsearch", extra_inp=True, sort=True)
test_intal_outs_array(lambda arr, s: arr.index(s) if s in arr else -1, "binsearch", extra_inp=True, extra_inp_from_arr=True, sort=True)
if 13 in choices or use_all:
test_intal_outs_array(lambda arr, s: sorted(arr), "sort", check_sort=True)
test_intal_outs_array(lambda arr, s: sorted(arr), "sort", check_sort=True, sort=True)
if 14 in choices or use_all:
test_intal_outs_array(coin_row_problem, "coinrow", max1=10*100)
test_intal_outs_array(coin_row_problem, "coinrow", max1=10*100, sort=True)
@KulkarniKaustubh
Copy link

Try chmod u+x intal, this will make sure that the executable you generated using the main.c file can be executed.

The error was because I had not downloaded main.c. The tests worked fine after that 👍.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment