Kumite (ko͞omiˌtā) is the practice of taking techniques learned from Kata and applying them through the act of freestyle sparring.
You can create a new kumite by providing some initial code and optionally some test cases. From there other warriors can spar with you, by enhancing, refactoring and translating your code. There is no limit to how many warriors you can spar with.
A great use for kumite is to begin an idea for a kata as one. You can collaborate with other code warriors until you have it right, then you can convert it to a kata.
We shall see.
#import <Foundation/Foundation.h>
// Nope - the bug has not been fixed yet :(
void test_function() {
[PreloadedTest printTestMessage];
}
@implementation TestSuite
- (void)testDummy
{
test_function();
UKPass();
}
@end
Since I have to work on an Android project which doesn't use Gradle as a build tool, so I always have to find the aar library and extract the classes.jar file from it. Doing it manually was very boring. So I decided to write my own Python (because it's interpreted) script to do this task. The code I have written works very well, but it can be improved by making it cross-platform, efficient, etc.
So let's start to improve it.
Gist: https://gist.github.com/pavi2410/b1ba0ae03e4b459846c72453204394a6
Note that you have to run this script on your PC, unfortunately.
import zipfile, os
cd = os.getcwd()
for file in os.listdir(cd):
if file.endswith(".aar"):
print("Got aar: " + file)
with zipfile.ZipFile(cd + "\\" + file) as aar:
aar.extract("classes.jar", cd)
print("Extracted aar")
os.rename("classes.jar", os.path.splitext(file)[0] + ".jar")
Write a function that:
- returns "Fizz" for multiples of 3
- returns "Buzz" for multiples of 5
- returns "FizzBuzz" for multiples of both 3 and 5
Any other number should return the number as string.
export function fizzBuzz(input: number): string {
const output: string = `${input % 3 === 0 ? "Fizz" : ""}${input % 5 === 0 ? "Buzz" : ""}`;
return output.length > 0 ? output : input.toString(10);
}
/// <reference path="/runner/typings/mocha/index.d.ts" />
/// <reference path="/runner/typings/chai/index.d.ts" />
import solution = require('./solution');
import { assert } from "chai";
describe("solution", () => {
it("Divisible By Three", () => {
assert.equal(solution.fizzBuzz(3), "Fizz");
assert.equal(solution.fizzBuzz(12), "Fizz");
})
it("Divisible By Five", () => {
assert.equal(solution.fizzBuzz(5), "Buzz");
assert.equal(solution.fizzBuzz(95), "Buzz");
})
it("Divisible By Three And Five", () => {
assert.equal(solution.fizzBuzz(15), "FizzBuzz");
assert.equal(solution.fizzBuzz(90), "FizzBuzz");
})
it("Not Divisible By Three Or Five", () => {
assert.equal(solution.fizzBuzz(1), "1");
assert.equal(solution.fizzBuzz(7), "7");
});
});
Please go to same kumite on the preview site to run these tests correctly :)
Example Task
Compute the sum of two integers.
Constraints
-10**9 <= a, b <= 10**9
Example Solutions
-
add
: Correct solution -
add1
: Incorrect solution -
add2
: Solution that timeouts -
add3
: Solution that cheats
You can uncomment each line at the bottom of Code
section to see how the tests combat the invalid solutions in different ways.
Example Test Fixture
@Test.describe(name)
@Test.it(name)
@Test.timeout(sec)
-
Test.assert_equals
andTest.assert_not_equals
are non-blocking by default -
Test.assert_not_equals
can now prevent cheating with magic methods
For more complete list of features and guide on how to write a test fixture, consult this page on GitHub Wiki.
# Correct solution
def add(a, b): return a + b
# Incorrect solution
def add1(a, b): return a | b
# Solution that timeouts
def add2(a, b):
while a: a, b = a-1, b+1
return b
# Solution that cheats
def add3(a, b):
class X(object):
def __eq__(self, other): return True
def __ne__(self, other): return True
def __gt__(self, other): return True
def __lt__(self, other): return True
def __ge__(self, other): return True
def __le__(self, other): return True
return X()
#add = add1
#add = add2
#add = add3
@Test.describe('Add two integers')
def _describe():
def test_one(a, b, c=None):
if c is None: c = a + b
@Test.timeout(0.01)
def do():
Test.assert_equals(add(a, b), c)
Test.assert_not_equals(add(a, b), c+1)
@Test.it('Basic tests')
def _it1():
test_cases = [(0, 0, 0), (1, 2, 3), (-1, -2, -3), (10**9, 10**9, 2 * 10**9), (-10**9, 10**9, 0)]
for a, b, c in test_cases:
test_one(a, b, c)
@Test.it('Random tests')
def _it2():
from random import randint
def r(): return randint(-10**9, 10**9)
for _ in range(100):
test_one(r(), r())
C has a weak type system that can be easily violated. The sole purpose of the type system is to inform the program how to view/interpret a certain memory block/space. It doesn't take much effort to convince C to view a particular memory space in a completely different manner than previously intended which could lead to interesting behavior ;)
Addendum: Following a bit of additional experimentation, it would appear that it is also possible to reassign value(s) under a pointer that views the given memory space in a completely unintended manner. However, I suspect this may be bordering on undefined behavior which means it may not work properly on all operating systems :p
// See the test cases for the real fun ;)
#include <criterion/criterion.h>
Test(dummy_test, should_compile_correctly) {
srand(time(0));
int n = rand(); // n is a (pseudo-)randomly generated 32-bit integer
printf("The original value of `n` is: %d\n", n);
int *p = &n; // Obtain the memory address of the integer `n`
char *a = p; // Now the memory space containing `n` is viewed
// as a sequence of 4 characters through this pointer
printf("When viewed as a sequence of 4 characters, `n` becomes: %c%c%c%c\n", a[0], a[1], a[2], a[3]);
printf("Now we reassign the 4 characters to be \"code\".\n");
// Reassigning the value of `n` through the integer-turned-character pointer
a[0] = 'c';
a[1] = 'o';
a[2] = 'd';
a[3] = 'e';
printf("Re-assignment of character sequence succeeded - the 4 characters are now: %c%c%c%c\n", a[0], a[1], a[2], a[3]);
printf("Lo and behold! The integer `n` now has a value of %d!\n", n);
cr_assert(1);
}
You have been asked to work out the area of number of rectangles.
The input to your function is a array of longs. If the arrays length is odd you should return void. Otherwise you should use adjacent pairs of longs to calculate the area.
For example if the input is {4,4,5,5,6,6,7,7} you should return {16, 25, 36, 49}.
public class Area {
public static long[] workOutArea(long[] values){
}
}
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runners.JUnit4;
public class SolutionTest {
@Test
public void testSomething() {
long[] val1 = {4l,4l,5l,5l,6l,6l,7l,7l};
Assert.assertArrayEquals(area.workOutArea(val1), new long[] {16l, 25l, 36l, 49l});
long[] val2 = {4l,4l,5l,5l,6l,6l,7l};
assertEquals(null, area.workOutArea(val2));
}
}
def blend(c1, c2):
if c1 == c2: return c1
colors = c1 + c2
if colors == "RB" or colors == "BR": return "G"
if colors == "RG" or colors == "GR": return "B"
if colors == "GB" or colors == "BG": return "R"
def triangle(row):
if len(row) == 1: return row
row = list(row)
for j in range(len(row)-1,0,-1):
for i in range(j):
row[i] = blend(row[i], row[i+1])
return row[0]
def _test(cases):
for _in, _out in cases:
test.assert_equals(triangle(_in), _out)
test.describe('Insane Coloured Triangles')
basic_cases = [
['B', 'B'],
['GB', 'R'],
['RRR', 'R'],
['RGBG', 'B'],
['RBRGBRB', 'G'],
['RBRGBRBGGRRRBGBBBGG', 'G']
]
test.it('Basic Tests')
_test(basic_cases)
This Kumite is a showcase for further possible improvements of Python testing framework cw-2.py
, which has been going through major changes. You can see already implemented features here (on Preview site).
Proposal
Improved expect_error()
, idea by Blind4Basics
As-is:
- Test if the function throws an error. It doesn't matter which exception it exactly throws.
To-be:
- Test if the function throws an error, which is an instance of the given
Exception
class.
# BaseException >> Exception
def f1(): raise Exception()
# BaseException >> Exception >> ArithmeticError >> ZeroDivisionError
def f2(): return 1 // 0
# BaseException >> Exception >> LookupError >> KeyError
def f3(): return {}[1]
def f0(): pass
@test.describe('expect_error, previous version')
def d1():
for f in (f0, f1, f2, f3):
test.expect_error('Should raise something', f)
def expect_error(message, function, class_=Exception):
passed = False
try: function()
except class_: passed = True
except: pass
test.expect(passed, message)
excn = ('Exception', 'ArithmeticError', 'ZeroDivisionError', 'LookupError', 'KeyError', 'OSError')
exc = (Exception, ArithmeticError, ZeroDivisionError, LookupError, KeyError, OSError)
@test.describe('expect_error, new version')
def d2():
@test.it('f0 raises nothing')
def i0():
expect_error('f0 did not raise any exception', f0)
for i in range(6):
expect_error('f0 did not raise {}'.format(excn[i]), f0, exc[i])
@test.it('f1 raises Exception')
def i1():
expect_error('f1 did not raise Exception', f1)
for i in range(6):
expect_error('f1 did not raise {}'.format(excn[i]), f1, exc[i])
@test.it('f2 raises Exception >> ArithmeticError >> ZeroDivisionError')
def i2():
expect_error('f2 did not raise Exception', f2)
for i in range(6):
expect_error('f2 did not raise {}'.format(excn[i]), f2, exc[i])
@test.it('f3 raises Exception >> LookupError >> KeyError')
def i3():
expect_error('f3 did not raise Exception', f3)
for i in range(6):
expect_error('f3 did not raise {}'.format(excn[i]), f3, exc[i])
[1, 1, 2] ==> 2
[17, 17, 3, 17, 17, 17, 17] ==> 3
Subtle arr.reduce(:^)
solutions dose not works on [x,y,y,y]
fromat. Take a look at the Test Cases.
The key to problem was found, size of the array must be odd: Y^Y n times give 0, and 0^X gives X
# Find stray number
def find_stray(n)
n.reduce(:^)
end
x = rand(1..100)
y = rand(1..100)
describe "Solution" do
it "should test for something" do
Test.assert_equals(find_stray([x,y,y]), x, "[x,y,y] works")
Test.assert_equals(find_stray([x,y,y,y]), x, "[x,y,y,y] DOSE NOT works")
Test.assert_equals(find_stray([x,y,y,y,y]), x, "[x,y,y,y,y] works")
end
end