Initial commit

This commit is contained in:
Thibaud Gasser 2024-01-23 14:32:21 +01:00
commit 2898a6bd38
12 changed files with 493 additions and 0 deletions

16
.gitignore vendored Normal file
View File

@ -0,0 +1,16 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

7
README.md Normal file
View File

@ -0,0 +1,7 @@
# Codewars solutions in python
## Quickstart
```console
$ pip install git+https://github.com/codewars/python-test-framework.git#egg=codewars_test
```

View File

@ -0,0 +1,68 @@
# https://www.codewars.com/kata/5f24315eff32c4002efcfc6a
import inspect
# https://docs.python.org/3.8/reference/datamodel.html#customizing-class-creation
# https://snarky.ca/unravelling-pythons-classes/
# https://gist.github.com/tmr232/c7214d62607ba1fc0e0a2e82d7e041cd
class DispatchProxy:
def __init__(self, name):
self.registry = {}
self.name = name
def register(self, f):
print(f"register {inspect.signature(f)}")
argcount = f.__code__.co_argcount
self.registry[argcount] = f
"""
def decorator(func):
argcount = f.__code__.co_argcount
self.registry[argcount] = f
return func
return decorator
"""
def __call__(self, *args):
argcount = len(args) + 1 # add 1 because the first argument of a method is "self"
if argcount in self.registry:
resolved = self.registry[argcount]
print(f"resolved: {resolved.__name__}{inspect.signature(resolved)}")
return resolved(self, *args)
else:
raise AttributeError(f"No matching function for args: {args}")
class MyNamespace(dict):
def __getitem__(self, key):
#(f"get {key}")
return super().__getitem__(key)
def __setitem__(self, key, value):
#sign = inspect.signature(value) if callable(value) else value
#print(f"set {key} {value}")
# already exists => overload
is_method = callable(value) and not value.__name__.startswith("__")
if is_method and key in self:
m = self[key]
if not isinstance(m, DispatchProxy):
m = DispatchProxy(self)
m.register(self[key])
m.register(value)
super().__setitem__(key, m)
else:
super().__setitem__(key, value)
class Meta(type):
@classmethod
def __prepare__(cls, name, bases):
return MyNamespace()
def __new__(cls, name, bases, dct):
x = super().__new__(cls, name, bases, dct)
return x
def __init__(self, name, bases, attrs):
super(Meta, self).__init__(name, bases, attrs)

View File

@ -0,0 +1,160 @@
import codewars_test as test
from overload import Meta
cng_msg = 'Dont change the properties of class.'
sld_work = 'Function overloading should work.'
@test.describe('Python Recipes #1 : Function Overloading')
def _():
# implement meta class -----
def build(): # returning class to regenerate accordingly.
class Overload(metaclass=Meta):
CLS_VAR = 42
def __init__(self):
self.a = 1
self.no = 'This is "No parameter" function.'
self.single = 'This is "Single parameter" function'
self.two = 'This is "Two parameter" function'
self.three = 'This is "Three parameter" function'
def foo(self):
return self.no
def foo(self, x):
return self.single + ':' + str(x)
def foo(self, x, y):
return self.two + ':' + str(x) + ',' + str(y)
def foo(self, x, y, z):
return self.three + ':' + str(x) + ',' + str(y) + ',' + str(z)
def extra(self):
return 'This is extra method.'
return Overload
@test.describe('Sample tests')
def _():
overload = build()
obj = overload()
@test.it('Verifying access')
def _():
test.assert_equals(obj.a, 1, cng_msg)
test.assert_equals(obj.no, 'This is "No parameter" function.', cng_msg)
test.assert_equals(obj.single, 'This is "Single parameter" function', cng_msg)
test.assert_equals(obj.two, 'This is "Two parameter" function', cng_msg)
test.assert_equals(obj.three, 'This is "Three parameter" function', cng_msg)
test.assert_equals(obj.extra(), 'This is extra method.', cng_msg)
test.assert_equals(obj.CLS_VAR, 42, cng_msg)
@test.it('Verifying overloading feature')
def _():
test.assert_equals(obj.foo(), 'This is "No parameter" function.', sld_work)
test.assert_equals(obj.foo(1), 'This is "Single parameter" function:1', sld_work)
test.assert_equals(obj.foo(1,2), 'This is "Two parameter" function:1,2', sld_work)
test.assert_equals(obj.foo(1,2,3), 'This is "Three parameter" function:1,2,3', sld_work)
@test.it('Verifying overloading feature after adding new methods :1')
def _():
def foo(self, a, b, c, d):
return self.a + a + b + c + d
def foo1(self, a, b):
return 'Overwritten'
overload.foo = foo
test.assert_equals(obj.foo(), 'This is "No parameter" function.', sld_work)
test.assert_equals(obj.foo(1), 'This is "Single parameter" function:1', sld_work)
test.assert_equals(obj.foo(1,2), 'This is "Two parameter" function:1,2', sld_work)
test.assert_equals(obj.foo(1,2,3), 'This is "Three parameter" function:1,2,3', sld_work)
test.assert_equals(obj.foo(1,2,3,4), 11, sld_work)
overload.foo = foo1
test.assert_equals(obj.foo(1,2), 'Overwritten', sld_work)
@test.it('Verifying overloading feature after adding new methods :2')
def _():
def boo1(self):
return self.a
def boo2(self, a):
return self.a + a
def unique(self, a, b):
return a + b
overload.boo = boo1
overload.boo = boo2
obj.nothing = '123'
overload.unique = unique
test.assert_equals(obj.boo(), 1, sld_work)
test.assert_equals(obj.boo(1), 2, sld_work)
test.assert_equals(obj.unique(1, 2), 3, sld_work)
test.assert_equals(obj.nothing, '123', sld_work)
@test.describe('Verify the absence of unwanted sharing of methods between different classes')
def _():
class Unshare(metaclass=Meta):
def foo(self,a,b): return 'unshared!'
unsh=Unshare()
@test.it('The new foo function in Unshare class should be used')
def _():
test.assert_equals(unsh.foo(1,2), 'unshared!')
@test.it('Previous implementations of "foo" in other classes shouldn\'t be visible from a freshly built class')
def _():
test.expect_error("Your function didn't raise any exception", lambda: unsh.foo(1), Exception)
test.expect_error("Your function should raise AttributeError", lambda: unsh.foo(1), AttributeError)
@test.it('Previous method with the same signature in other classes shouldn\'t be affected')
def _():
test.assert_equals(obj.foo(1,2), 'Overwritten')
@test.it('Class level variables are still working as expected')
def _():
def over(): obj.CLS_VAR=-42
def write(): obj.HAHA=msg
test.expect_no_error("Class level variables can be overriden", over)
test.assert_equals(obj.CLS_VAR, -42, "Class variable Overload.CLS_VAR hasn't been overriden")
msg = 'This is another class variable'
test.expect_no_error("New class level variables can be defined", write)
test.assert_equals(obj.HAHA, msg, "New class level variables can be defined and accessed")
@test.it('Undefined methods or variables should raise AttributeError')
def _():
test.expect_error('Undefined attributes/mehtods should raise AttributeError',
lambda: overload.NEW_CLS_VAR, AttributeError)
test.expect_error('Undefined attributes/mehtods should raise AttributeError',
lambda: obj.ABCD, AttributeError)
test.expect_error('Undefined attributes/mehtods should raise AttributeError',
lambda: obj.randomFuncName(), AttributeError)
@test.it('undefined overloaded methods (wrong number of arguments should raise AttributeError)')
def _():
test.expect_error('Undefined attributes/mehtods should raise AttributeError',
lambda: overload.foo(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), AttributeError)

Binary file not shown.

Binary file not shown.

41
prime_streaming/helper.py Normal file
View File

@ -0,0 +1,41 @@
from threading import Thread
import functools
def timeout(timeout):
def deco(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
res = [Exception('function [%s] timeout [%s seconds] exceeded!' % (func.__name__, timeout))]
def newFunc():
try:
res[0] = func(*args, **kwargs)
except Exception as e:
res[0] = e
t = Thread(target=newFunc)
t.daemon = True
try:
t.start()
t.join(timeout)
except Exception as je:
print ('error starting thread')
raise je
ret = res[0]
if isinstance(ret, BaseException):
raise ret
return ret
return wrapper
return deco
if __name__ == "__main__":
@timeout(timeout=5)
def long_running_function():
import time
time.sleep(10)
return "Function completed successfully"
try:
result = long_running_function()
print(result)
except TimeoutError as e:
print(e)

View File

@ -0,0 +1,5 @@
home = C:\Python312
include-system-site-packages = false
version = 3.12.0
executable = C:\Python312\python.exe
command = C:\Python312\python.exe -m venv C:\Users\GASSERTH\source\bidouilles\codewars\prime_streaming

58
prime_streaming/stream.py Normal file
View File

@ -0,0 +1,58 @@
import numpy as np
def sieve_np(limit):
if limit < 2:
return []
# Create a boolean array "is_prime" and initialize all entries as True
is_prime = np.ones(limit + 1, dtype=bool)
is_prime[0:2] = False # 0 and 1 are not prime numbers
for p in range(2, int(limit**0.5) + 1):
if is_prime[p]:
# Use array slicing to mark all multiples of p as not prime
is_prime[p**2 : limit + 1 : p] = False
# Create a list of prime numbers using NumPy's where function
primes = np.where(is_prime)[0]
return primes.tolist()
def sieve(max_n):
s = [True] * (max_n + 1)
p = 2
while p**2 <= max_n:
if s[p]:
for i in range(p**2, max_n + 1, p):
s[i] = False
p += 1
primes = [p for p in range(2, max_n + 1) if s[p]]
return primes
def sieve_of_eratosthenes(limit):
if limit < 2:
return []
# Create a boolean array "prime[0..limit]" and initialize all entries as True
prime = [True] * (limit + 1)
prime[0] = prime[1] = False # 0 and 1 are not prime numbers
p = 2
while p**2 <= limit:
if prime[p]:
# Update all multiples of p starting from p^2
prime[p**2 : limit + 1 : p] = [False] * len(prime[p**2 : limit + 1 : p])
p += 1
# Create a list of prime numbers
primes = [p for p in range(2, limit + 1) if prime[p]]
return primes
class Primes:
primes = sieve(25_000_000)
@staticmethod
def stream():
yield from Primes.primes

View File

@ -0,0 +1,34 @@
# https://www.codewars.com/kata/53f40dff5f9d31b813000774/train/python
# Recover a secret string from random triplets
def recoverSecret(triplets):
transposed = list(zip(*triplets))
sets = [set(x) for x in transposed]
return sets
return (sets[0],
sets[1] - sets[0],
sets[2] - sets[1] - sets[0])
test_data = [[['t','u','p'], ['w','h','i'], ['t','s','u'], ['a','t','s'], ['h','a','p'], ['t','i','s'], ['w','h','s']],
[['t', 's', 'f'], ['a', 's', 'u'], ['m', 'a', 'f'], ['a', 'i', 'n'], ['s', 'u', 'n'], ['m', 'f', 'u'], ['a', 't', 'h'], ['t', 'h', 'i'], ['h', 'i', 'f'], ['m', 'h', 'f'], ['a', 'u', 'n'], ['m', 'a', 't'], ['f', 'u', 'n'], ['h', 's', 'n'], ['a', 'i', 's'], ['m', 's', 'n'], ['m', 's', 'u']],
[['t', 's', 'f'], ['a', 's', 'u'], ['m', 'a', 'f'], ['a', 'i', 'n'], ['s', 'u', 'n'], ['m', 'f', 'u'], ['a', 't', 'h'], ['t', 'h', 'i'], ['h', 'i', 'f'], ['m', 'h', 'f'], ['a', 'u', 'n'], ['m', 'a', 't'], ['f', 'u', 'n'], ['h', 's', 'n'], ['a', 'i', 's'], ['m', 's', 'n'], ['m', 's', 'u']],
[['g', 'a', 's'], ['o', 'g', 's'], ['c', 'n', 't'], ['c', 'o', 'n'], ['a', 't', 's'], ['g', 'r', 't'], ['r', 't', 's'], ['c', 'r', 'a'], ['g', 'a', 't'], ['n', 'g', 's'], ['o', 'a', 's']]]
def main():
# tests
triplets = [['t','u','p'], ['w','h','i'], ['t','s','u'], ['a','t','s'], ['h','a','p'], ['t','i','s'], ['w','h','s']]
res = recoverSecret(triplets)
#assert res == "whatisup"
triplets = [['t', 's', 'f'], ['a', 's', 'u'], ['m', 'a', 'f'], ['a', 'i', 'n'], ['s', 'u', 'n'], ['m', 'f', 'u'], ['a', 't', 'h'], ['t', 'h', 'i'], ['h', 'i', 'f'], ['m', 'h', 'f'], ['a', 'u', 'n'], ['m', 'a', 't'], ['f', 'u', 'n'], ['h', 's', 'n'], ['a', 'i', 's'], ['m', 's', 'n'], ['m', 's', 'u']]
res = recoverSecret(triplets)
#assert res == "mathisfun"
triplets = [['g', 'a', 's'], ['o', 'g', 's'], ['c', 'n', 't'], ['c', 'o', 'n'], ['a', 't', 's'], ['g', 'r', 't'], ['r', 't', 's'], ['c', 'r', 'a'], ['g', 'a', 't'], ['n', 'g', 's'], ['o', 'a', 's']]
res = recoverSecret(triplets)
#assert res == "congrats"
if __name__ == "__main__":
main()

11
sum_strings/solution.py Normal file
View File

@ -0,0 +1,11 @@
# https://www.codewars.com/kata/5324945e2ece5e1f32000370/
def sum_strings(s1, s2):
res = ""
carry = 0
s1, s2 = s1.zfill(len(s2)), s2.zfill(len(s1))
for d1, d2 in zip(s1[::-1], s2[::-1]):
carry, total = divmod(int(d1) + int(d2) + carry, 10)
res += str(total)
return (str(carry) + res[::-1]).lstrip('0') or '0'

93
sum_strings/tests.py Normal file
View File

@ -0,0 +1,93 @@
import random
import codewars_test as test
from string import digits
from solution import sum_strings
def rand_str_num():
return ''.join(
random.choice(digits)
for _ in range(random.randint(0, 1000))
)
def __this_is_the_sol(x, y):
out, ret = '', 0
for c_x, c_y in zip(x.zfill(len(y))[::-1], y.zfill(len(x))[::-1]):
ret, d = divmod(int(c_x) + int(c_y) + ret, 10)
out += str(d)
out = f"{out}{'1' * ret}"[::-1] or '0'
return out if len(out) < 2 else out.lstrip('0')
@test.describe('Basic tests')
def test_examples():
@test.it('Example tests')
def basic_tests():
test.assert_equals(sum_strings("1", "1"), "2")
test.assert_equals(sum_strings("123", "456"), "579")
@test.it('Fixed tests')
def basic_test():
test.assert_equals(sum_strings("10", "20"), "30")
test.assert_equals(sum_strings("200", "100"), "300")
test.assert_equals(sum_strings("99", "1"), "100")
test.assert_equals(sum_strings("42", "69"), "111")
test.assert_equals(sum_strings("2999", "302"), "3301")
test.assert_equals(sum_strings("800", "9567"), "10367")
test.assert_equals(sum_strings("00103", "08567"), "8670")
test.assert_equals(sum_strings("0", "0"), "0")
test.assert_equals(sum_strings("0", "5"), "5")
test.assert_equals(sum_strings("5", "0"), "5")
test.assert_equals(sum_strings("0", ""), "0")
test.assert_equals(sum_strings("", ""), "0")
test.assert_equals(sum_strings("9999", ""), "9999")
test.assert_equals(sum_strings("", "9999"), "9999")
test.assert_equals(sum_strings("9999999999999999", "1"), "10000000000000000")
test.assert_equals(sum_strings("1", "9999999999999999"), "10000000000000000")
test.assert_equals(
sum_strings(
"712569312664357328695151392",
"8100824045303269669937"
),
"712577413488402631964821329",
)
test.assert_equals(
sum_strings(
"50095301248058391139327916261",
"81055900096023504197206408605"
),
"131151201344081895336534324866"
)
@test.it('Random tests')
def basic_test():
x = rand_str_num()
y = rand_str_num()
for _ in range(100):
test.assert_equals(
sum_strings(x, y),
__this_is_the_sol(x, y)
)
@test.it('Is it fast enough?')
def basic_test():
x = str(random.randint(10, 99)) * random.randint(1_000_000, 1_100_000)
y = str(random.randint(10, 99)) * random.randint(1_000_000, 1_100_000)
test.expect(
sum_strings(x, y) == __this_is_the_sol(x, y),
"big test failed"
)