mirror of https://github.com/exaloop/codon.git
CR pt. 1
parent
ce268c81a3
commit
8d72ff8cfa
|
@ -3,7 +3,7 @@
|
|||
|
||||
def _heapify(
|
||||
arr: Array[T], begin: int, end: int, keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
):
|
||||
"""
|
||||
Makes the array a heap from [begin, end).
|
||||
"""
|
||||
|
@ -24,7 +24,7 @@ def _heapify(
|
|||
|
||||
def _heap_sort(
|
||||
arr: Array[T], begin: int, end: int, keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
):
|
||||
if end - begin < 2:
|
||||
return
|
||||
|
||||
|
@ -46,7 +46,7 @@ def _heap_sort(
|
|||
|
||||
def heap_sort_array(
|
||||
collection: Array[T], size: int, keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
):
|
||||
"""
|
||||
Heap Sort
|
||||
Sorts the array inplace.
|
||||
|
@ -56,7 +56,7 @@ def heap_sort_array(
|
|||
|
||||
def heap_sort_inplace(
|
||||
collection: List[T], keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
):
|
||||
"""
|
||||
Heap Sort
|
||||
Sorts the list inplace.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
def _insertion_sort(
|
||||
arr: Array[T], begin: int, end: int, keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
):
|
||||
i = begin + 1
|
||||
while i < end:
|
||||
x = arr[i]
|
||||
|
@ -17,7 +17,7 @@ def _insertion_sort(
|
|||
|
||||
def insertion_sort_array(
|
||||
collection: Array[T], size: int, keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
):
|
||||
"""
|
||||
Insertion Sort
|
||||
Sorts the array inplace.
|
||||
|
@ -27,7 +27,7 @@ def insertion_sort_array(
|
|||
|
||||
def insertion_sort_inplace(
|
||||
collection: List[T], keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
):
|
||||
"""
|
||||
Insertion Sort
|
||||
Sorts the list inplace.
|
||||
|
|
|
@ -162,14 +162,14 @@ def _partition_right(
|
|||
|
||||
def _sort2(
|
||||
arr: Array[T], i: int, j: int, keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
):
|
||||
if keyf(arr[j]) < keyf(arr[i]):
|
||||
arr[i], arr[j] = arr[j], arr[i]
|
||||
|
||||
|
||||
def _sort3(
|
||||
arr: Array[T], i: int, j: int, k: int, keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
):
|
||||
_sort2(arr, i, j, keyf)
|
||||
_sort2(arr, j, k, keyf)
|
||||
_sort2(arr, i, j, keyf)
|
||||
|
@ -184,7 +184,7 @@ def _pdq_sort(
|
|||
leftmost: bool,
|
||||
T: type,
|
||||
S: type,
|
||||
) -> void:
|
||||
):
|
||||
while True:
|
||||
size = end - begin
|
||||
if size < INSERTION_SORT_THRESHOLD:
|
||||
|
@ -292,7 +292,7 @@ def _pdq_sort(
|
|||
|
||||
def pdq_sort_array(
|
||||
collection: Array[T], size: int, keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
):
|
||||
"""
|
||||
Pattern-defeating Quicksort
|
||||
By Orson Peters, published at https://github.com/orlp/pdqsort
|
||||
|
@ -304,7 +304,7 @@ def pdq_sort_array(
|
|||
|
||||
def pdq_sort_inplace(
|
||||
collection: List[T], keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
):
|
||||
"""
|
||||
Pattern-defeating Quicksort
|
||||
By Orson Peters, published at https://github.com/orlp/pdqsort
|
||||
|
|
|
@ -32,11 +32,11 @@ def _med3(
|
|||
)
|
||||
|
||||
|
||||
def _swap(i: int, j: int, a: Array[T], T: type) -> void:
|
||||
def _swap(i: int, j: int, a: Array[T], T: type):
|
||||
a[i], a[j] = a[j], a[i]
|
||||
|
||||
|
||||
def _vecswap(i: int, j: int, n: int, a: Array[T], T: type) -> void:
|
||||
def _vecswap(i: int, j: int, n: int, a: Array[T], T: type):
|
||||
while n > 0:
|
||||
_swap(i, j, a)
|
||||
i += 1
|
||||
|
@ -45,14 +45,14 @@ def _vecswap(i: int, j: int, n: int, a: Array[T], T: type) -> void:
|
|||
|
||||
|
||||
def _qsort(
|
||||
arr: Array[T], frm: int, cnt: int, keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
arr: Array[T], frm: int, cnt: int, key: Callable[[T], S], T: type, S: type
|
||||
):
|
||||
if cnt <= 7:
|
||||
i = frm + 1
|
||||
while i < frm + cnt:
|
||||
j = i
|
||||
while j > frm and not (
|
||||
keyf(arr[j - 1]) < keyf(arr[j]) or keyf(arr[j - 1]) == keyf(arr[j])
|
||||
key(arr[j - 1]) < key(arr[j]) or key(arr[j - 1]) == key(arr[j])
|
||||
):
|
||||
_swap(j, j - 1, arr)
|
||||
j -= 1
|
||||
|
@ -65,10 +65,10 @@ def _qsort(
|
|||
|
||||
if cnt > 40:
|
||||
s = cnt // 8
|
||||
lo = _med3(lo, lo + s, lo + 2 * s, arr, keyf)
|
||||
mid = _med3(mid - s, mid, mid + s, arr, keyf)
|
||||
hi = _med3(hi - 2 * s, hi - s, hi, arr, keyf)
|
||||
mid = _med3(lo, mid, hi, arr, keyf)
|
||||
lo = _med3(lo, lo + s, lo + 2 * s, arr, key)
|
||||
mid = _med3(mid - s, mid, mid + s, arr, key)
|
||||
hi = _med3(hi - 2 * s, hi - s, hi, arr, key)
|
||||
mid = _med3(lo, mid, hi, arr, key)
|
||||
|
||||
_swap(frm, mid, arr)
|
||||
a = frm
|
||||
|
@ -78,15 +78,15 @@ def _qsort(
|
|||
|
||||
while True:
|
||||
while b <= c and (
|
||||
keyf(arr[b]) < keyf(arr[frm]) or keyf(arr[b]) == keyf(arr[frm])
|
||||
key(arr[b]) < key(arr[frm]) or key(arr[b]) == key(arr[frm])
|
||||
):
|
||||
if keyf(arr[b]) == keyf(arr[frm]):
|
||||
if key(arr[b]) == key(arr[frm]):
|
||||
_swap(a, b, arr)
|
||||
a += 1
|
||||
b += 1
|
||||
|
||||
while c >= b and not keyf(arr[c]) < keyf(arr[frm]):
|
||||
if keyf(arr[c]) == keyf(arr[frm]):
|
||||
while c >= b and not key(arr[c]) < key(arr[frm]):
|
||||
if key(arr[c]) == key(arr[frm]):
|
||||
_swap(c, d, arr)
|
||||
d -= 1
|
||||
c -= 1
|
||||
|
@ -106,44 +106,44 @@ def _qsort(
|
|||
|
||||
span = b - a
|
||||
if span > 1:
|
||||
_qsort(arr, frm, span, keyf)
|
||||
_qsort(arr, frm, span, key)
|
||||
|
||||
span = d - c
|
||||
if span > 1:
|
||||
_qsort(arr, hi - span, span, keyf)
|
||||
_qsort(arr, hi - span, span, key)
|
||||
|
||||
|
||||
def qsort_array(
|
||||
collection: Array[T], size: int, keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
collection: Array[T], size: int, key: Callable[[T], S], T: type, S: type
|
||||
):
|
||||
"""
|
||||
Pattern-defeating Quicksort
|
||||
By Orson Peters, published at https://github.com/orlp/pdqsort
|
||||
|
||||
Sorts the array inplace.
|
||||
"""
|
||||
_qsort(collection, 0, size, keyf)
|
||||
_qsort(collection, 0, size, key)
|
||||
|
||||
|
||||
def qsort_inplace(
|
||||
collection: List[T], keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
collection: List[T], key: Callable[[T], S], T: type, S: type
|
||||
):
|
||||
"""
|
||||
Pattern-defeating Quicksort
|
||||
By Orson Peters, published at https://github.com/orlp/pdqsort
|
||||
|
||||
Sorts the list inplace.
|
||||
"""
|
||||
qsort_array(collection.arr, collection.len, keyf)
|
||||
qsort_array(collection.arr, collection.len, key)
|
||||
|
||||
|
||||
def qsort(collection: List[T], keyf: Callable[[T], S], T: type, S: type) -> List[T]:
|
||||
def qsort(collection: List[T], key: Callable[[T], S], T: type, S: type) -> List[T]:
|
||||
"""
|
||||
Pattern-defeating Quicksort
|
||||
By Orson Peters, published at https://github.com/orlp/pdqsort
|
||||
|
||||
Returns a sorted list.
|
||||
"""
|
||||
newlst = copy(collection)
|
||||
qsort_inplace(newlst, keyf)
|
||||
return newlst
|
||||
collection = collection[:]
|
||||
qsort_inplace(collection, key)
|
||||
return collection
|
||||
|
|
|
@ -86,16 +86,13 @@ def string_search_rabin_karp(
|
|||
yield len(text) - len(pattern)
|
||||
|
||||
|
||||
def computeLPArray(pattern: str, len_pat: int) -> List[int]:
|
||||
def compute_lp_array(pattern: str, len_pat: int) -> List[int]:
|
||||
"""
|
||||
Return a list containing the length of the maximum matching
|
||||
proper prefix of the pattern[0, 1, ..., i]
|
||||
"""
|
||||
len = 0 # length of the previous longest prefix
|
||||
lp = List[
|
||||
int
|
||||
]() # longest proper prefix will hold the longest prefix values for pattern
|
||||
lp.append(0)
|
||||
lp = [0] # longest proper prefix will hold the longest prefix values for pattern
|
||||
i = 1
|
||||
|
||||
while i < len_pat:
|
||||
|
@ -112,7 +109,7 @@ def computeLPArray(pattern: str, len_pat: int) -> List[int]:
|
|||
return lp
|
||||
|
||||
|
||||
def string_search_KMP(text: str, pattern: str) -> Generator[int]:
|
||||
def string_search_kmp(text: str, pattern: str) -> Generator[int]:
|
||||
"""
|
||||
Knuth-Morris-Pratt algorithm
|
||||
Return a list containing the position of each index
|
||||
|
@ -123,7 +120,7 @@ def string_search_KMP(text: str, pattern: str) -> Generator[int]:
|
|||
yield i
|
||||
return
|
||||
|
||||
lp_array = computeLPArray(pattern, len(pattern))
|
||||
lp_array = compute_lp_array(pattern, len(pattern))
|
||||
i, j = 0, 0 # indices for text and pattern
|
||||
while i < len(text):
|
||||
if pattern[j] == text[i]:
|
||||
|
@ -148,7 +145,7 @@ def replace_interleave(self, new: str, maxcount: int) -> str:
|
|||
"""
|
||||
|
||||
j = 0
|
||||
res = List[str]()
|
||||
res = []
|
||||
# insert the new string for maxcount <= len(self) times.
|
||||
for i in range(len(self)):
|
||||
if i + 1 > maxcount:
|
||||
|
@ -168,7 +165,7 @@ def replace_delete_substring(self, old: str, new: str, maxcount: int) -> str:
|
|||
Returns a string deleting any instances of the 'old' string in self and
|
||||
replaceing it with the 'new' string.
|
||||
"""
|
||||
li = list(string_search_KMP(self, old))
|
||||
li = list(string_search_kmp(self, old))
|
||||
|
||||
# no matches
|
||||
if len(li) == 0:
|
||||
|
@ -185,7 +182,7 @@ def replace_delete_substring(self, old: str, new: str, maxcount: int) -> str:
|
|||
assert result_len >= 0
|
||||
|
||||
j = li[0]
|
||||
res = List[str]()
|
||||
res = []
|
||||
res.append(self[0:j])
|
||||
|
||||
# replace the old substring with the new substring
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#
|
||||
# 8. By copying, installing or otherwise using Python 3.10.2, Licensee agrees
|
||||
# to be bound by the terms and conditions of this License Agreement.
|
||||
#
|
||||
# Timsort by Tim Peters, published at https://github.com/python/cpython/blob/master/Objects/listobject.c#L2187
|
||||
|
||||
BLOCK_SIZE = 64
|
||||
CACHELINE_SIZE = 64
|
||||
|
@ -94,7 +96,7 @@ def _merge_compute_minrun(n: int) -> int:
|
|||
return n + r
|
||||
|
||||
|
||||
def _reverse_sortslice(arr: Array[T], begin: int, end: int, T: type) -> void:
|
||||
def _reverse_sortslice(arr: Array[T], begin: int, end: int, T: type):
|
||||
if end - begin < 2:
|
||||
return
|
||||
arr[begin], arr[end - 1] = arr[end - 1], arr[begin]
|
||||
|
@ -186,7 +188,7 @@ def _merge_with_gallop(
|
|||
keyf: Callable[[T], S],
|
||||
T: type,
|
||||
S: type,
|
||||
) -> void:
|
||||
):
|
||||
min_gallop = MIN_GALLOP
|
||||
|
||||
combined = Array[T](a[1] + b[1])
|
||||
|
@ -284,7 +286,7 @@ def _merge_at(
|
|||
keyf: Callable[[T], S],
|
||||
T: type,
|
||||
S: type,
|
||||
) -> void:
|
||||
):
|
||||
start_a, len_a = a
|
||||
start_b, len_b = b
|
||||
|
||||
|
@ -308,7 +310,7 @@ def _merge_collapse(
|
|||
keyf: Callable[[T], S],
|
||||
T: type,
|
||||
S: type,
|
||||
) -> void:
|
||||
):
|
||||
if len(stack) <= 1:
|
||||
return
|
||||
|
||||
|
@ -357,7 +359,7 @@ def _final_merge(
|
|||
keyf: Callable[[T], S],
|
||||
T: type,
|
||||
S: type,
|
||||
) -> void:
|
||||
):
|
||||
while len(stack) > 1:
|
||||
C = stack.pop()
|
||||
B = stack.pop()
|
||||
|
@ -367,7 +369,7 @@ def _final_merge(
|
|||
|
||||
def _tim_sort(
|
||||
arr: Array[T], begin: int, end: int, keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
):
|
||||
if end - begin < 2:
|
||||
return
|
||||
|
||||
|
@ -393,35 +395,17 @@ def _tim_sort(
|
|||
|
||||
def tim_sort_array(
|
||||
collection: Array[T], size: int, keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
"""
|
||||
Timsort
|
||||
By Tim Peters, published at https://github.com/python/cpython/blob/master/Objects/listobject.c#L2187
|
||||
|
||||
Sorts the array inplace.
|
||||
"""
|
||||
):
|
||||
_tim_sort(collection, 0, size, keyf)
|
||||
|
||||
|
||||
def tim_sort_inplace(
|
||||
collection: List[T], keyf: Callable[[T], S], T: type, S: type
|
||||
) -> void:
|
||||
"""
|
||||
Timsort
|
||||
By Tim Peters, published at https://github.com/python/cpython/blob/master/Objects/listobject.c#L2187
|
||||
|
||||
Sorts the list inplace.
|
||||
"""
|
||||
):
|
||||
tim_sort_array(collection.arr, collection.len, keyf)
|
||||
|
||||
|
||||
def tim_sort(collection: List[T], keyf: Callable[[T], S], T: type, S: type) -> List[T]:
|
||||
"""
|
||||
Timsort
|
||||
By Tim Peters, published at https://github.com/python/cpython/blob/master/Objects/listobject.c#L2187
|
||||
|
||||
Returns a sorted list.
|
||||
"""
|
||||
newlst = list(collection)
|
||||
tim_sort_inplace(newlst, keyf)
|
||||
return newlst
|
||||
|
|
|
@ -61,8 +61,7 @@ def bisect_left(
|
|||
"""
|
||||
if lo < 0:
|
||||
raise ValueError("lo must be non-negative")
|
||||
if hi is None:
|
||||
hi = len(a)
|
||||
hi: int = len(a) if hi is None else hi
|
||||
while lo < hi:
|
||||
mid = (lo + hi) // 2
|
||||
if a[mid] < x:
|
||||
|
@ -89,8 +88,7 @@ def bisect_right(
|
|||
"""
|
||||
if lo < 0:
|
||||
raise ValueError("lo must be non-negative")
|
||||
if hi is None:
|
||||
hi = len(a)
|
||||
hi: int = len(a) if hi is None else hi
|
||||
while lo < hi:
|
||||
mid = (lo + hi) // 2
|
||||
if x < a[mid]:
|
||||
|
@ -102,7 +100,7 @@ def bisect_right(
|
|||
|
||||
def insort_left(
|
||||
a: List[T], x: S, lo: int = 0, hi: Optional[int] = None, T: type, S: type
|
||||
) -> void:
|
||||
):
|
||||
"""
|
||||
Insert item x in list a, and keep it sorted assuming a is sorted.
|
||||
|
||||
|
@ -117,7 +115,7 @@ def insort_left(
|
|||
|
||||
def insort_right(
|
||||
a: List[T], x: S, lo: int = 0, hi: Optional[int] = None, T: type, S: type
|
||||
) -> void:
|
||||
):
|
||||
"""
|
||||
Insert item x in list a, and keep it sorted assuming a is sorted.
|
||||
|
||||
|
|
|
@ -1,26 +1,28 @@
|
|||
# (c) 2022 Exaloop Inc. All rights reserved.
|
||||
|
||||
from internal.types.optional import unwrap
|
||||
|
||||
|
||||
class deque:
|
||||
T: type
|
||||
_arr: Array[T]
|
||||
_head: int
|
||||
_tail: int
|
||||
_maxlen: int
|
||||
T: type
|
||||
|
||||
def __init__(self, arr: Array[T], head: int, tail: int, maxlen: int) -> void:
|
||||
def __init__(self, arr: Array[T], head: int, tail: int, maxlen: int):
|
||||
self._arr = arr
|
||||
self._head = head
|
||||
self._tail = tail
|
||||
self._maxlen = maxlen
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._arr = Array[T](16)
|
||||
self._head = 0
|
||||
self._tail = 0
|
||||
self._maxlen = -1
|
||||
|
||||
def __init__(self, maxlen: int) -> void:
|
||||
def __init__(self, maxlen: int):
|
||||
cap = 1
|
||||
while cap < maxlen:
|
||||
cap *= 2
|
||||
|
@ -29,7 +31,7 @@ class deque:
|
|||
self._tail = 0
|
||||
self._maxlen = maxlen
|
||||
|
||||
def __init__(self, it: Generator[T]) -> void:
|
||||
def __init__(self, it: Generator[T]):
|
||||
self._arr = Array[T](16)
|
||||
self._head = 0
|
||||
self._tail = 0
|
||||
|
@ -41,7 +43,7 @@ class deque:
|
|||
def maxlen(self) -> int:
|
||||
return self._maxlen
|
||||
|
||||
def _double_cap(self) -> void:
|
||||
def _double_cap(self):
|
||||
p = self._head
|
||||
n = len(self._arr)
|
||||
r = n - p
|
||||
|
@ -55,7 +57,7 @@ class deque:
|
|||
self._head = 0
|
||||
self._tail = n
|
||||
|
||||
def _check_not_empty(self) -> void:
|
||||
def _check_not_empty(self):
|
||||
if not self:
|
||||
raise IndexError("pop from an empty deque")
|
||||
|
||||
|
@ -65,7 +67,7 @@ class deque:
|
|||
def __len__(self) -> int:
|
||||
return (self._tail - self._head) & (len(self._arr) - 1)
|
||||
|
||||
def appendleft(self, x: T) -> void:
|
||||
def appendleft(self, x: T):
|
||||
self._head = (self._head - 1) & (len(self._arr) - 1)
|
||||
self._arr[self._head] = x
|
||||
if self._maxlen >= 0 and len(self) > self._maxlen:
|
||||
|
@ -73,7 +75,7 @@ class deque:
|
|||
if self._head == self._tail:
|
||||
self._double_cap()
|
||||
|
||||
def append(self, x: T) -> void:
|
||||
def append(self, x: T):
|
||||
self._arr[self._tail] = x
|
||||
self._tail = (self._tail + 1) & (len(self._arr) - 1)
|
||||
if self._maxlen >= 0 and len(self) > self._maxlen:
|
||||
|
@ -92,7 +94,7 @@ class deque:
|
|||
self._tail = (self._tail - 1) & (len(self._arr) - 1)
|
||||
return self._arr[self._tail]
|
||||
|
||||
def clear(self) -> void:
|
||||
def clear(self):
|
||||
self._head = 0
|
||||
self._tail = 0
|
||||
|
||||
|
@ -120,7 +122,7 @@ class deque:
|
|||
def __repr__(self) -> str:
|
||||
return repr(List[T](iter(self)))
|
||||
|
||||
def _idx_check(self, idx: int, msg: str) -> void:
|
||||
def _idx_check(self, idx: int, msg: str):
|
||||
if self._head == self._tail or idx >= len(self) or idx < 0:
|
||||
raise IndexError(msg)
|
||||
|
||||
|
@ -145,9 +147,9 @@ class deque:
|
|||
|
||||
@tuple
|
||||
class _CounterItem:
|
||||
T: type
|
||||
element: T
|
||||
count: int
|
||||
T: type
|
||||
|
||||
def __eq__(self, other: _CounterItem[T]) -> bool:
|
||||
return self.count == other.count
|
||||
|
@ -171,17 +173,14 @@ class _CounterItem:
|
|||
class Counter(Dict[T, int]):
|
||||
T: type
|
||||
|
||||
def _add(self, element: T) -> void:
|
||||
self.increment(element)
|
||||
|
||||
def __init__(self, elements: Generator[T]) -> void:
|
||||
def __init__(self, elements: Generator[T]):
|
||||
self._init()
|
||||
self.update(elements)
|
||||
|
||||
def __init__(self, other: Counter[T]) -> void:
|
||||
def __init__(self, other: Counter[T]):
|
||||
self._init_from(other)
|
||||
|
||||
def __init__(self, other: Dict[T, int]) -> void:
|
||||
def __init__(self, other: Dict[T, int]):
|
||||
self._init_from(other)
|
||||
|
||||
def elements(self) -> Generator[T]:
|
||||
|
@ -202,14 +201,14 @@ class Counter(Dict[T, int]):
|
|||
else:
|
||||
from heapq import heapify, heapreplace
|
||||
|
||||
n: int = ~n
|
||||
n: int = n
|
||||
|
||||
if n == 1:
|
||||
top: Optional[_CounterItem] = None
|
||||
for t in self.items():
|
||||
if top is None or t[1] > top.count:
|
||||
top = t
|
||||
return [~top]
|
||||
return [unwrap(top)]
|
||||
|
||||
if n <= 0:
|
||||
return List[_CounterItem](capacity=0)
|
||||
|
@ -227,31 +226,31 @@ class Counter(Dict[T, int]):
|
|||
result.sort(reverse=True)
|
||||
return result
|
||||
|
||||
def subtract(self, elements: Generator[T]) -> void:
|
||||
def subtract(self, elements: Generator[T]):
|
||||
for a in elements:
|
||||
self.increment(a, -1)
|
||||
|
||||
def subtract(self, other: Counter[T]) -> void:
|
||||
def subtract(self, other: Counter[T]):
|
||||
for k, v in other.items():
|
||||
self.increment(k, -v)
|
||||
|
||||
def subtract(self, other: Dict[T, int]) -> void:
|
||||
def subtract(self, other: Dict[T, int]):
|
||||
for k, v in other.items():
|
||||
self.increment(k, -v)
|
||||
|
||||
def update(self, elements: Generator[T]) -> void:
|
||||
def update(self, elements: Generator[T]):
|
||||
for a in elements:
|
||||
self._add(a)
|
||||
self.increment(a)
|
||||
|
||||
def update(self, other: Counter[T]) -> void:
|
||||
def update(self, other: Counter[T]):
|
||||
for k, v in other.items():
|
||||
self.increment(k, by=v)
|
||||
|
||||
def update(self, other: Dict[T, int]) -> void:
|
||||
def update(self, other: Dict[T, int]):
|
||||
for k, v in other.items():
|
||||
self.increment(k, by=v)
|
||||
|
||||
def update(self) -> void:
|
||||
def update(self):
|
||||
pass
|
||||
|
||||
def total(self) -> int:
|
||||
|
@ -263,7 +262,7 @@ class Counter(Dict[T, int]):
|
|||
def __getitem__(self, key: T) -> int:
|
||||
return self.get(key, 0)
|
||||
|
||||
def __delitem__(self, key: T) -> void:
|
||||
def __delitem__(self, key: T):
|
||||
x = self._kh_get(key)
|
||||
if x != self._kh_end():
|
||||
self._kh_del(x)
|
||||
|
@ -282,11 +281,6 @@ class Counter(Dict[T, int]):
|
|||
def __copy__(self) -> Counter[T]:
|
||||
return Counter[T](self)
|
||||
|
||||
def _del_non_positives(self) -> void:
|
||||
for k, v in self.items():
|
||||
if v <= 0:
|
||||
del self[k]
|
||||
|
||||
def __iadd__(self, other: Counter[T]) -> Counter[T]:
|
||||
for k, v in other.items():
|
||||
self.increment(k, by=v)
|
||||
|
@ -348,13 +342,18 @@ class Counter(Dict[T, int]):
|
|||
result |= other
|
||||
return result
|
||||
|
||||
def __dict_do_op_throws__[F, Z](self, key: T, other: Z, op: F):
|
||||
def __dict_do_op_throws__(self, key: T, other: Z, op: F, F: type, Z: type):
|
||||
self.__dict_do_op__(key, other, 0, op)
|
||||
|
||||
def _del_non_positives(self):
|
||||
for k, v in self.items():
|
||||
if v <= 0:
|
||||
del self[k]
|
||||
|
||||
|
||||
@extend
|
||||
class Dict:
|
||||
def __init__(self: Dict[K, int], other: Counter[K]) -> void:
|
||||
def __init__(self: Dict[K, int], other: Counter[K]):
|
||||
self._init_from(other)
|
||||
|
||||
|
||||
|
|
|
@ -179,12 +179,12 @@ def _iso_week1_monday(year: int) -> int:
|
|||
return week1_monday
|
||||
|
||||
|
||||
def _check_delta_day_range(days: int) -> void:
|
||||
def _check_delta_day_range(days: int):
|
||||
if not (-MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS):
|
||||
raise OverflowError(f"days={days}; must have magnitude <= {MAX_DELTA_DAYS}")
|
||||
|
||||
|
||||
def _check_date_args(year: int, month: int, day: int) -> void:
|
||||
def _check_date_args(year: int, month: int, day: int):
|
||||
if not (MINYEAR <= year <= MAXYEAR):
|
||||
raise ValueError(f"year {year} is out of range")
|
||||
if not (1 <= month <= 12):
|
||||
|
@ -193,7 +193,7 @@ def _check_date_args(year: int, month: int, day: int) -> void:
|
|||
raise ValueError("day is out of range for month")
|
||||
|
||||
|
||||
def _check_time_args(hour: int, minute: int, second: int, microsecond: int) -> void:
|
||||
def _check_time_args(hour: int, minute: int, second: int, microsecond: int):
|
||||
if not (0 <= hour <= 23):
|
||||
raise ValueError("hour must be in 0..23")
|
||||
if not (0 <= minute <= 59):
|
||||
|
@ -295,7 +295,7 @@ def _parse_digits(digits: str, num_digits: int) -> Tuple[str, int]:
|
|||
return str(p, len(digits) - num_digits), var
|
||||
|
||||
|
||||
def _isoformat_error(s: str) -> void:
|
||||
def _isoformat_error(s: str):
|
||||
raise ValueError(f"Invalid isoformat string: {s}")
|
||||
|
||||
|
||||
|
|
|
@ -68,10 +68,10 @@ import os
|
|||
class GetoptError:
|
||||
_hdr: ExcHeader
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._hdr = ("GetoptError", "", "", "", 0, 0)
|
||||
|
||||
def __init__(self, message: str) -> void:
|
||||
def __init__(self, message: str):
|
||||
self._hdr = ("GetoptError", message, "", "", 0, 0)
|
||||
|
||||
@property
|
||||
|
@ -79,9 +79,6 @@ class GetoptError:
|
|||
return self._hdr.msg
|
||||
|
||||
|
||||
# Return:
|
||||
# has_arg?
|
||||
# full option name
|
||||
def long_has_args(opt: str, longopts: List[str]) -> Tuple[bool, str]:
|
||||
possibilities = [o for o in longopts if o.startswith(opt)]
|
||||
if not possibilities:
|
||||
|
@ -122,7 +119,7 @@ def do_longs(
|
|||
optarg, args = args[0], args[1:]
|
||||
elif optarg != "":
|
||||
raise GetoptError(f"option --{opt} must not have an argument")
|
||||
opts.append(("--" + opt, optarg))
|
||||
opts.append((f"--{opt}", optarg))
|
||||
return opts, args
|
||||
|
||||
|
||||
|
@ -145,7 +142,7 @@ def do_shorts(
|
|||
raise GetoptError(f"option -{opt} requires argument")
|
||||
optstring, args = args[0], args[1:]
|
||||
optarg, optstring = optstring, ""
|
||||
opts.append(("-" + opt, optarg))
|
||||
opts.append((f"-{opt}", optarg))
|
||||
return opts, args
|
||||
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
# (c) 2022 Exaloop Inc. All rights reserved.
|
||||
|
||||
# TODO: heapq.merge
|
||||
|
||||
# 'heap' is a heap at all indices >= startpos, except possibly for pos. pos
|
||||
# is the index of a leaf with a possibly out-of-order value. Restore the
|
||||
# heap invariant.
|
||||
def _siftdown(heap: List[T], startpos: int, pos: int, T: type) -> void:
|
||||
def _siftdown(heap: List[T], startpos: int, pos: int, T: type):
|
||||
newitem = heap[pos]
|
||||
# Follow the path to the root, moving parents down until finding a place
|
||||
# newitem fits.
|
||||
|
@ -20,7 +18,7 @@ def _siftdown(heap: List[T], startpos: int, pos: int, T: type) -> void:
|
|||
heap[pos] = newitem
|
||||
|
||||
|
||||
def _siftup(heap: List[T], pos: int, T: type) -> void:
|
||||
def _siftup(heap: List[T], pos: int, T: type):
|
||||
endpos = len(heap)
|
||||
startpos = pos
|
||||
newitem = heap[pos]
|
||||
|
@ -41,7 +39,7 @@ def _siftup(heap: List[T], pos: int, T: type) -> void:
|
|||
_siftdown(heap, startpos, pos)
|
||||
|
||||
|
||||
def _siftdown_max(heap: List[T], startpos: int, pos: int, T: type) -> void:
|
||||
def _siftdown_max(heap: List[T], startpos: int, pos: int, T: type):
|
||||
"Maxheap variant of _siftdown"
|
||||
newitem = heap[pos]
|
||||
# Follow the path to the root, moving parents down until finding a place
|
||||
|
@ -57,7 +55,7 @@ def _siftdown_max(heap: List[T], startpos: int, pos: int, T: type) -> void:
|
|||
heap[pos] = newitem
|
||||
|
||||
|
||||
def _siftup_max(heap: List[T], pos: int, T: type) -> void:
|
||||
def _siftup_max(heap: List[T], pos: int, T: type):
|
||||
"Maxheap variant of _siftup"
|
||||
endpos = len(heap)
|
||||
startpos = pos
|
||||
|
@ -79,7 +77,7 @@ def _siftup_max(heap: List[T], pos: int, T: type) -> void:
|
|||
_siftdown_max(heap, startpos, pos)
|
||||
|
||||
|
||||
def heappush(heap: List[T], item: T, T: type) -> void:
|
||||
def heappush(heap: List[T], item: T, T: type):
|
||||
"""Push item onto heap, maintaining the heap invariant."""
|
||||
heap.append(item)
|
||||
_siftdown(heap, 0, len(heap) - 1)
|
||||
|
@ -119,7 +117,7 @@ def heappushpop(heap: List[T], item: T, T: type) -> T:
|
|||
return item
|
||||
|
||||
|
||||
def heapify(x: List[T], T: type) -> void:
|
||||
def heapify(x: List[T], T: type):
|
||||
"""Transform list into a heap, in-place, in $O(len(x))$ time."""
|
||||
n = len(x)
|
||||
# Transform bottom-up. The largest index there's any point to looking at
|
||||
|
@ -150,7 +148,7 @@ def _heapreplace_max(heap: List[T], item: T, T: type) -> T:
|
|||
return returnitem
|
||||
|
||||
|
||||
def _heapify_max(x: List[T], T: type) -> void:
|
||||
def _heapify_max(x: List[T], T: type):
|
||||
"""Transform list into a maxheap, in-place, in O(len(x)) time."""
|
||||
n = len(x)
|
||||
for i in reversed(range(n // 2)):
|
||||
|
|
|
@ -24,7 +24,7 @@ import internal.c_stubs as _C
|
|||
def next(g: Generator[T], default: Optional[T] = None, T: type) -> T:
|
||||
if g.done():
|
||||
if default:
|
||||
return ~default
|
||||
return unwrap(default)
|
||||
else:
|
||||
raise StopIteration()
|
||||
return g.next()
|
||||
|
@ -34,16 +34,16 @@ from C import seq_print_full(str, cobj)
|
|||
|
||||
|
||||
class Set:
|
||||
T: type
|
||||
items: List[T]
|
||||
T: type
|
||||
|
||||
def __init__(self) -> void:
|
||||
self.items = List[T]()
|
||||
def __init__(self):
|
||||
self.items = []
|
||||
|
||||
def __iter__(self) -> Generator[T]:
|
||||
yield from self.items
|
||||
|
||||
def add(self, what: T) -> void:
|
||||
def add(self, what: T):
|
||||
if what not in self.items:
|
||||
self.items.append(what)
|
||||
|
||||
|
@ -55,14 +55,14 @@ class Set:
|
|||
|
||||
|
||||
class Dict:
|
||||
K: type
|
||||
V: type
|
||||
keys: List[K]
|
||||
values: List[V]
|
||||
K: type
|
||||
V: type
|
||||
|
||||
def __init__(self) -> void:
|
||||
self.keys = List[K]()
|
||||
self.values = List[V]()
|
||||
def __init__(self):
|
||||
self.keys = []
|
||||
self.values = []
|
||||
|
||||
def __iter__(self) -> Generator[K]:
|
||||
yield from self.keys
|
||||
|
@ -78,7 +78,7 @@ class Dict:
|
|||
i = self.keys.index(key)
|
||||
return self.values[i]
|
||||
|
||||
def __setitem__(self, key: K, val: V) -> void:
|
||||
def __setitem__(self, key: K, val: V):
|
||||
i = self.keys.index(key)
|
||||
if i != -1:
|
||||
self.values[i] = val
|
||||
|
@ -94,7 +94,7 @@ class Dict:
|
|||
if n == 0:
|
||||
return "{}"
|
||||
else:
|
||||
lst = List[str]()
|
||||
lst = []
|
||||
lst.append("{")
|
||||
first = True
|
||||
for k, v in self.items():
|
||||
|
@ -128,7 +128,7 @@ class str:
|
|||
raise ValueError("nope")
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "'" + self + "'"
|
||||
return f"'{self}'"
|
||||
|
||||
|
||||
from internal.builtin import *
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# (c) 2022 Exaloop Inc. All rights reserved.
|
||||
|
||||
from internal.gc import alloc_atomic, free
|
||||
from internal.types.optional import unwrap
|
||||
|
||||
|
||||
@tuple
|
||||
|
@ -19,7 +20,7 @@ def id(x) -> int:
|
|||
_stdout = _C.seq_stdout()
|
||||
|
||||
|
||||
def print(*args, sep: str = " ", end: str = "\n", file=_stdout, flush: bool = False) -> void:
|
||||
def print(*args, sep: str = " ", end: str = "\n", file=_stdout, flush: bool = False):
|
||||
"""
|
||||
Print args to the text stream file.
|
||||
"""
|
||||
|
@ -134,7 +135,7 @@ def ord(s: str) -> int:
|
|||
"""
|
||||
if len(s) != 1:
|
||||
raise TypeError(
|
||||
"ord() expected a character, but string of length " + str(len(s)) + " found"
|
||||
f"ord() expected a character, but string of length {len(s)} found"
|
||||
)
|
||||
return int(s.ptr[0])
|
||||
|
||||
|
@ -162,7 +163,7 @@ def next(g: Generator[T], default: Optional[T] = None, T: type) -> T:
|
|||
"""
|
||||
if g.done():
|
||||
if default:
|
||||
return ~default
|
||||
return unwrap(default)
|
||||
else:
|
||||
raise StopIteration()
|
||||
return g.next()
|
||||
|
@ -367,7 +368,7 @@ class int:
|
|||
|
||||
if end != p + n:
|
||||
raise ValueError(
|
||||
"invalid literal for int() with base " + str(base) + ": " + s
|
||||
f"invalid literal for int() with base {base}: {s}"
|
||||
)
|
||||
|
||||
return result
|
||||
|
|
|
@ -49,6 +49,6 @@ def dlsym(lib, name: str, Fn: type) -> Fn:
|
|||
return Fn(fn)
|
||||
|
||||
|
||||
def dlclose(handle: cobj) -> void:
|
||||
def dlclose(handle: cobj):
|
||||
if c_dlclose(handle) != i32(0):
|
||||
raise CError(dlerror())
|
||||
|
|
|
@ -8,25 +8,25 @@ class File:
|
|||
buf: Ptr[byte]
|
||||
fp: cobj
|
||||
|
||||
def __init__(self, fp: cobj) -> void:
|
||||
def __init__(self, fp: cobj):
|
||||
self.fp = fp
|
||||
self._reset()
|
||||
|
||||
def __init__(self, path: str, mode: str) -> void:
|
||||
def __init__(self, path: str, mode: str):
|
||||
self.fp = _C.fopen(path.c_str(), mode.c_str())
|
||||
if not self.fp:
|
||||
raise IOError("file " + path + " could not be opened")
|
||||
raise IOError(f"file {path} could not be opened")
|
||||
self._reset()
|
||||
|
||||
def _errcheck(self, msg: str) -> void:
|
||||
def _errcheck(self, msg: str):
|
||||
err = int(_C.ferror(self.fp))
|
||||
if err:
|
||||
raise IOError("file I/O error: " + msg)
|
||||
raise IOError(f"file I/O error: {msg}")
|
||||
|
||||
def __enter__(self) -> void:
|
||||
def __enter__(self):
|
||||
pass
|
||||
|
||||
def __exit__(self) -> void:
|
||||
def __exit__(self):
|
||||
self.close()
|
||||
|
||||
def __iter__(self) -> Generator[str]:
|
||||
|
@ -36,12 +36,12 @@ class File:
|
|||
def readlines(self) -> List[str]:
|
||||
return [l for l in self]
|
||||
|
||||
def write(self, s: str) -> void:
|
||||
def write(self, s: str):
|
||||
self._ensure_open()
|
||||
_C.fwrite(s.ptr, 1, len(s), self.fp)
|
||||
self._errcheck("error in write")
|
||||
|
||||
def __file_write_gen__(self, g: Generator[T], T: type) -> void:
|
||||
def __file_write_gen__(self, g: Generator[T], T: type):
|
||||
for s in g:
|
||||
self.write(str(s))
|
||||
|
||||
|
@ -57,14 +57,14 @@ class File:
|
|||
self._errcheck("error in tell")
|
||||
return ret
|
||||
|
||||
def seek(self, offset: int, whence: int) -> void:
|
||||
def seek(self, offset: int, whence: int):
|
||||
_C.fseek(self.fp, offset, i32(whence))
|
||||
self._errcheck("error in seek")
|
||||
|
||||
def flush(self) -> void:
|
||||
def flush(self):
|
||||
_C.fflush(self.fp)
|
||||
|
||||
def close(self) -> void:
|
||||
def close(self):
|
||||
if self.fp:
|
||||
_C.fclose(self.fp)
|
||||
self.fp = cobj()
|
||||
|
@ -72,11 +72,11 @@ class File:
|
|||
_C.free(self.buf)
|
||||
self._reset()
|
||||
|
||||
def _ensure_open(self) -> void:
|
||||
def _ensure_open(self):
|
||||
if not self.fp:
|
||||
raise IOError("I/O operation on closed file")
|
||||
|
||||
def _reset(self) -> void:
|
||||
def _reset(self):
|
||||
self.buf = Ptr[byte]()
|
||||
self.sz = 0
|
||||
|
||||
|
@ -105,11 +105,11 @@ class File:
|
|||
break
|
||||
|
||||
|
||||
def _gz_errcheck(stream: cobj) -> void:
|
||||
def _gz_errcheck(stream: cobj):
|
||||
errnum = i32(0)
|
||||
msg = _C.gzerror(stream, __ptr__(errnum))
|
||||
if msg and msg[0]:
|
||||
raise IOError("zlib error: " + str(msg, _C.strlen(msg)))
|
||||
raise IOError(f"zlib error: {str(msg, _C.strlen(msg))}")
|
||||
|
||||
|
||||
class gzFile:
|
||||
|
@ -117,14 +117,14 @@ class gzFile:
|
|||
buf: Ptr[byte]
|
||||
fp: cobj
|
||||
|
||||
def __init__(self, fp: cobj) -> void:
|
||||
def __init__(self, fp: cobj):
|
||||
self.fp = fp
|
||||
self._reset()
|
||||
|
||||
def __init__(self, path: str, mode: str) -> void:
|
||||
def __init__(self, path: str, mode: str):
|
||||
self.fp = _C.gzopen(path.c_str(), mode.c_str())
|
||||
if not self.fp:
|
||||
raise IOError("file " + path + " could not be opened")
|
||||
raise IOError(f"file {path} could not be opened")
|
||||
self._reset()
|
||||
|
||||
def _getline(self) -> int:
|
||||
|
@ -154,13 +154,13 @@ class gzFile:
|
|||
for a in self._iter():
|
||||
yield a.__ptrcopy__()
|
||||
|
||||
def __enter__(self) -> void:
|
||||
def __enter__(self):
|
||||
pass
|
||||
|
||||
def __exit__(self) -> void:
|
||||
def __exit__(self):
|
||||
self.close()
|
||||
|
||||
def close(self) -> void:
|
||||
def close(self):
|
||||
if self.fp:
|
||||
_C.gzclose(self.fp)
|
||||
self.fp = cobj()
|
||||
|
@ -171,12 +171,12 @@ class gzFile:
|
|||
def readlines(self) -> List[str]:
|
||||
return [l for l in self]
|
||||
|
||||
def write(self, s: str) -> void:
|
||||
def write(self, s: str):
|
||||
self._ensure_open()
|
||||
_C.gzwrite(self.fp, s.ptr, u32(len(s)))
|
||||
_gz_errcheck(self.fp)
|
||||
|
||||
def __file_write_gen__(self, g: Generator[T], T: type) -> void:
|
||||
def __file_write_gen__(self, g: Generator[T], T: type):
|
||||
for s in g:
|
||||
self.write(str(s))
|
||||
|
||||
|
@ -185,7 +185,7 @@ class gzFile:
|
|||
_gz_errcheck(self.fp)
|
||||
return ret
|
||||
|
||||
def seek(self, offset: int, whence: int) -> void:
|
||||
def seek(self, offset: int, whence: int):
|
||||
_C.gzseek(self.fp, offset, i32(whence))
|
||||
_gz_errcheck(self.fp)
|
||||
|
||||
|
@ -209,11 +209,11 @@ class gzFile:
|
|||
else:
|
||||
break
|
||||
|
||||
def _ensure_open(self) -> void:
|
||||
def _ensure_open(self):
|
||||
if not self.fp:
|
||||
raise IOError("I/O operation on closed file")
|
||||
|
||||
def _reset(self) -> void:
|
||||
def _reset(self):
|
||||
self.buf = cobj()
|
||||
self.sz = 0
|
||||
|
||||
|
@ -227,6 +227,9 @@ def gzopen(path: str, mode: str = "r") -> gzFile:
|
|||
|
||||
|
||||
def is_binary(path: str) -> bool:
|
||||
# https://stackoverflow.com/questions/898669/how-can-i-detect-if-a-file-is-binary-non-text-in-python/7392391#7392391
|
||||
# Can get both false positive and false negatives, but still is a
|
||||
# clever approach that works for the large majority of files
|
||||
textchars = {7, 8, 9, 10, 12, 13, 27} | set(iter(range(0x20, 0x100))) - {0x7F}
|
||||
with open(path, "rb") as f:
|
||||
header = f.read(1024)
|
||||
|
|
|
@ -34,7 +34,7 @@ class __internal__:
|
|||
if idx < 0:
|
||||
idx += len
|
||||
if idx < 0 or idx >= len:
|
||||
raise IndexError("tuple index " + str(idx) + " out of range 0.." + str(len))
|
||||
raise IndexError(f"tuple index {idx} out of range 0..{len}")
|
||||
return idx
|
||||
|
||||
def tuple_getitem(t: T, idx: int, T: type, E: type) -> E:
|
||||
|
@ -73,19 +73,16 @@ class __internal__:
|
|||
ret i{=T} %0
|
||||
|
||||
def seq_assert(file: str, line: int, msg: str) -> AssertionError:
|
||||
s = "Assert failed"
|
||||
if msg:
|
||||
s += ": " + msg
|
||||
s += " (" + file + ":" + line.__repr__() + ")"
|
||||
s = f": {msg}" if msg else ""
|
||||
s = f"Assert failed{s} ({file}:{line.__repr__()})"
|
||||
return AssertionError(s)
|
||||
|
||||
def seq_assert_test(file: str, line: int, msg: str) -> void:
|
||||
s = "\033[1;31mTEST FAILED:\033[0m " + file + " (line " + str(line) + ")"
|
||||
if msg:
|
||||
s += ": " + msg
|
||||
seq_print(s + "\n")
|
||||
def seq_assert_test(file: str, line: int, msg: str):
|
||||
s = f": {msg}" if msg else ""
|
||||
s = f"\033[1;31mTEST FAILED:\033[0m {file} (line {line}){s}\n"
|
||||
seq_print(s)
|
||||
|
||||
def check_errno(prefix: str) -> void:
|
||||
def check_errno(prefix: str):
|
||||
msg = seq_check_errno()
|
||||
if msg:
|
||||
raise OSError(prefix + msg)
|
||||
|
|
|
@ -13,19 +13,19 @@ def __ac_iseither(flag: Ptr[u32], i: int) -> int:
|
|||
return int(flag[i >> 4] >> u32((i & 0xF) << 1)) & 3
|
||||
|
||||
|
||||
def __ac_set_isdel_false(flag: Ptr[u32], i: int) -> void:
|
||||
def __ac_set_isdel_false(flag: Ptr[u32], i: int):
|
||||
flag[i >> 4] &= u32(~(1 << ((i & 0xF) << 1)))
|
||||
|
||||
|
||||
def __ac_set_isempty_false(flag: Ptr[u32], i: int) -> void:
|
||||
def __ac_set_isempty_false(flag: Ptr[u32], i: int):
|
||||
flag[i >> 4] &= u32(~(2 << ((i & 0xF) << 1)))
|
||||
|
||||
|
||||
def __ac_set_isboth_false(flag: Ptr[u32], i: int) -> void:
|
||||
def __ac_set_isboth_false(flag: Ptr[u32], i: int):
|
||||
flag[i >> 4] &= u32(~(3 << ((i & 0xF) << 1)))
|
||||
|
||||
|
||||
def __ac_set_isdel_true(flag: Ptr[u32], i: int) -> void:
|
||||
def __ac_set_isdel_true(flag: Ptr[u32], i: int):
|
||||
flag[i >> 4] |= u32(1 << ((i & 0xF) << 1))
|
||||
|
||||
|
||||
|
|
|
@ -77,12 +77,12 @@ def __codon_repr__(fig):
|
|||
_PY_INITIALIZED = False
|
||||
|
||||
|
||||
def init() -> void:
|
||||
def init():
|
||||
global _PY_INITIALIZED
|
||||
if _PY_INITIALIZED:
|
||||
return
|
||||
|
||||
LD = os.getenv("CODON_PYTHON", default="libpython." + dlext())
|
||||
LD = os.getenv("CODON_PYTHON", default=f"libpython.{dlext()}")
|
||||
hnd = dlopen(LD, RTLD_LOCAL | RTLD_NOW)
|
||||
|
||||
global PyUnicode_AsEncodedString
|
||||
|
@ -163,7 +163,7 @@ def init() -> void:
|
|||
_PY_INITIALIZED = True
|
||||
|
||||
|
||||
def ensure_initialized() -> void:
|
||||
def ensure_initialized():
|
||||
if not _PY_INITIALIZED:
|
||||
init()
|
||||
# raise ValueError("Python not initialized; make sure to 'import python'")
|
||||
|
@ -215,7 +215,7 @@ class pyobj:
|
|||
pyobj(obj).decref()
|
||||
return str.from_ptr(bts)
|
||||
|
||||
def exc_check() -> void:
|
||||
def exc_check():
|
||||
ptype, pvalue, ptraceback = cobj(), cobj(), cobj()
|
||||
PyErr_Fetch(__ptr__(ptype), __ptr__(pvalue), __ptr__(ptraceback))
|
||||
if ptype != cobj():
|
||||
|
@ -236,15 +236,15 @@ class pyobj:
|
|||
pyobj.exc_check()
|
||||
return _retval
|
||||
|
||||
def incref(self) -> void:
|
||||
def incref(self):
|
||||
Py_IncRef(self.p)
|
||||
|
||||
def decref(self) -> void:
|
||||
def decref(self):
|
||||
Py_DecRef(self.p)
|
||||
|
||||
def __call__(self, *args, **kwargs) -> pyobj:
|
||||
names = iter(kwargs.__dict__())
|
||||
kws = Dict[str, pyobj]()
|
||||
kws = dict[str, pyobj]()
|
||||
if staticlen(kwargs) > 0:
|
||||
kws = {next(names): i.__to_py__() for i in kwargs}
|
||||
return pyobj.exc_wrap(
|
||||
|
@ -256,7 +256,7 @@ class pyobj:
|
|||
pyobj.exc_check()
|
||||
return pyobj(t)
|
||||
|
||||
def _tuple_set(self, idx: int, val: pyobj) -> void:
|
||||
def _tuple_set(self, idx: int, val: pyobj):
|
||||
PyTuple_SetItem(self.p, idx, val.p)
|
||||
pyobj.exc_check()
|
||||
|
||||
|
@ -273,7 +273,7 @@ class pyobj:
|
|||
_PY_MODULE_CACHE[name] = m
|
||||
return m
|
||||
|
||||
def _exec(code: str) -> void:
|
||||
def _exec(code: str):
|
||||
ensure_initialized()
|
||||
PyRun_SimpleString(code.c_str())
|
||||
|
||||
|
@ -388,7 +388,7 @@ class Dict:
|
|||
return pyobj(pydict)
|
||||
|
||||
def __from_py__(d: pyobj) -> Dict[K, V]:
|
||||
b = Dict[K, V]()
|
||||
b = dict[K, V]()
|
||||
pos = 0
|
||||
k_ptr = cobj()
|
||||
v_ptr = cobj()
|
||||
|
|
|
@ -27,7 +27,7 @@ def sorted(
|
|||
|
||||
def _sort_list(
|
||||
self: List[T], key: Callable[[T], S], algorithm: str, T: type, S: type
|
||||
) -> void:
|
||||
):
|
||||
if algorithm == "tim":
|
||||
tim_sort_inplace(self, key)
|
||||
elif algorithm == "pdq":
|
||||
|
@ -39,7 +39,7 @@ def _sort_list(
|
|||
elif algorithm == "quick":
|
||||
qsort_inplace(self, key)
|
||||
else:
|
||||
raise ValueError("Algorithm '" + algorithm + "' does not exist")
|
||||
raise ValueError(f"Algorithm '{algorithm}' does not exist")
|
||||
|
||||
|
||||
@extend
|
||||
|
@ -49,11 +49,11 @@ class List:
|
|||
key=Optional[int](),
|
||||
algorithm: Optional[str] = None,
|
||||
reverse: bool = False,
|
||||
) -> void:
|
||||
alg = ~algorithm if algorithm else "tim"
|
||||
):
|
||||
algorithm: str = algorithm if algorithm else "tim"
|
||||
if isinstance(key, Optional):
|
||||
_sort_list(self, lambda x: x, alg)
|
||||
_sort_list(self, lambda x: x, algorithm)
|
||||
else:
|
||||
_sort_list(self, key, alg)
|
||||
_sort_list(self, key, algorithm)
|
||||
if reverse:
|
||||
self.reverse()
|
||||
|
|
|
@ -142,7 +142,7 @@ class str:
|
|||
def join(self, l: Generator[str]) -> str:
|
||||
if len(self) == 0:
|
||||
return str.cat(list(l))
|
||||
v = List[str]()
|
||||
v = []
|
||||
for a in l:
|
||||
v.append(a)
|
||||
v.append(self)
|
||||
|
@ -561,7 +561,7 @@ class str:
|
|||
if width <= len(self):
|
||||
return self
|
||||
|
||||
s = List[str]()
|
||||
s = []
|
||||
if self and (self[0] == "+" or self[0] == "-"):
|
||||
# move sign to beginning of string
|
||||
s.append(self[0])
|
||||
|
@ -577,7 +577,7 @@ class str:
|
|||
s.append(self)
|
||||
return "".join(s)
|
||||
|
||||
def count(self, sub: str, start: int = 0, end: int = 0x7FFFFFFFFFFFFFFF) -> int:
|
||||
def count(self, sub: str, start: int = 0, end: Optional[int] = None) -> int:
|
||||
"""
|
||||
str.count(sub[, start[, end]]) -> int
|
||||
|
||||
|
@ -585,13 +585,14 @@ class str:
|
|||
bytes str[start:end]. Optional arguments start and end are interpreted
|
||||
as in slice notation.
|
||||
"""
|
||||
end: int = end if end is not None else len(self)
|
||||
start, end = self._correct_indices(start, end)
|
||||
count = 0
|
||||
for _ in algorithms.filter_overlaps(self[start:end]._search(sub), len(sub)):
|
||||
count += 1
|
||||
return count
|
||||
|
||||
def find(self, sub: str, start: int = 0, end: int = 0x7FFFFFFFFFFFFFFF) -> int:
|
||||
def find(self, sub: str, start: int = 0, end: Optional[int] = None) -> int:
|
||||
"""
|
||||
str.find(sub [,start [,end]]) -> int
|
||||
|
||||
|
@ -601,6 +602,7 @@ class str:
|
|||
|
||||
Return -1 on failure.
|
||||
"""
|
||||
end: int = end if end is not None else len(self)
|
||||
start, end = self._correct_indices(start, end)
|
||||
pos = str._getfirst(self[start:end]._search(sub))
|
||||
|
||||
|
@ -615,7 +617,7 @@ class str:
|
|||
|
||||
return pos + start # add start position because of truncation
|
||||
|
||||
def rfind(self, sub: str, start: int = 0, end: int = 0x7FFFFFFFFFFFFFFF) -> int:
|
||||
def rfind(self, sub: str, start: int = 0, end: Optional[int] = None) -> int:
|
||||
"""
|
||||
str.rfind(sub [,start [,end]]) -> int
|
||||
|
||||
|
@ -625,6 +627,7 @@ class str:
|
|||
|
||||
Return -1 on failure.
|
||||
"""
|
||||
end: int = end if end is not None else len(self)
|
||||
start, end = self._correct_indices(start, end)
|
||||
pos = str._getfirst(self[start:end]._rsearch(sub))
|
||||
|
||||
|
@ -772,16 +775,16 @@ class str:
|
|||
return self._split_whitespace(
|
||||
maxsplit if maxsplit >= 0 else 0x7FFFFFFFFFFFFFFF
|
||||
)
|
||||
sepx = ~sep
|
||||
sep: str = sep
|
||||
|
||||
li = list(algorithms.filter_overlaps(self._search(sepx), len(sepx)))
|
||||
str_split = List[str]()
|
||||
li = list(algorithms.filter_overlaps(self._search(sep), len(sep)))
|
||||
str_split = []
|
||||
|
||||
# no delimiter found
|
||||
if len(li) == 0:
|
||||
return [self]
|
||||
|
||||
if len(sepx) > len(self):
|
||||
if len(sep) > len(self):
|
||||
return [self]
|
||||
|
||||
if maxsplit == 0:
|
||||
|
@ -805,11 +808,11 @@ class str:
|
|||
if li[j] - 1 == prev:
|
||||
str_split.append("")
|
||||
else:
|
||||
str_split.append(self[prev + len(sepx) : li[j]])
|
||||
str_split.append(self[prev + len(sep) : li[j]])
|
||||
prev = li[j]
|
||||
|
||||
if prev != len(self):
|
||||
str_split.append(self[prev + len(sepx) :])
|
||||
str_split.append(self[prev + len(sep) :])
|
||||
|
||||
return str_split
|
||||
|
||||
|
@ -827,17 +830,17 @@ class str:
|
|||
return self._rsplit_whitespace(
|
||||
maxsplit if maxsplit >= 0 else 0x7FFFFFFFFFFFFFFF
|
||||
)
|
||||
sepx = ~sep
|
||||
sep: str = sep
|
||||
|
||||
li = list(
|
||||
algorithms.rfilter_overlaps(reversed(list(self._search(sepx))), len(sepx))
|
||||
algorithms.rfilter_overlaps(reversed(list(self._search(sep))), len(sep))
|
||||
)
|
||||
str_split = List[str]()
|
||||
str_split = []
|
||||
end_of_li = len(li) - 1
|
||||
|
||||
if len(li) == 0:
|
||||
return [self]
|
||||
if len(sepx) > len(self):
|
||||
if len(sep) > len(self):
|
||||
return [self]
|
||||
if maxsplit == 0:
|
||||
return [self]
|
||||
|
@ -848,10 +851,10 @@ class str:
|
|||
prev = li[0]
|
||||
# append first part of string
|
||||
# if sep is found in the last index, add '' to separate
|
||||
if prev == len(self) - len(sepx):
|
||||
if prev == len(self) - len(sep):
|
||||
str_split.append("")
|
||||
else:
|
||||
str_split.append(self[prev + len(sepx) :])
|
||||
str_split.append(self[prev + len(sep) :])
|
||||
|
||||
# split the rest of the string according to separator
|
||||
if len(li) > 1 and maxsplit > 1:
|
||||
|
@ -860,7 +863,7 @@ class str:
|
|||
if li[j] + 1 == prev:
|
||||
str_split.append("")
|
||||
else:
|
||||
str_split.append(self[li[j] + len(sepx) : prev])
|
||||
str_split.append(self[li[j] + len(sep) : prev])
|
||||
prev = li[j]
|
||||
|
||||
if prev != 0:
|
||||
|
@ -882,7 +885,7 @@ class str:
|
|||
Line breaks are not included in the resulting list unless keepends
|
||||
is given and true.
|
||||
"""
|
||||
line_split = List[str]()
|
||||
line_split = []
|
||||
|
||||
prev = 0
|
||||
for i in range(len(self)):
|
||||
|
@ -953,7 +956,7 @@ class str:
|
|||
return line_split
|
||||
|
||||
def startswith(
|
||||
self, prefix: str, start: int = 0, end: int = 0x7FFFFFFFFFFFFFFF
|
||||
self, prefix: str, start: int = 0, end: Optional[int] = None
|
||||
) -> bool:
|
||||
"""
|
||||
str.startswith(prefix[, start[, end]]) -> bool
|
||||
|
@ -962,6 +965,7 @@ class str:
|
|||
With optional start, test str beginning at that position.
|
||||
With optional end, stop comparing str at that position.
|
||||
"""
|
||||
end: int = end if end is not None else len(self)
|
||||
if end < 0:
|
||||
end += len(self)
|
||||
elif start < 0:
|
||||
|
@ -981,9 +985,7 @@ class str:
|
|||
|
||||
return prefix == self[start : start + len(prefix)]
|
||||
|
||||
def endswith(
|
||||
self, suffix: str, start: int = 0, end: int = 0x7FFFFFFFFFFFFFFF
|
||||
) -> bool:
|
||||
def endswith(self, suffix: str, start: int = 0, end: Optional[int] = None) -> bool:
|
||||
"""
|
||||
str.endswith(prefix[, start[, end]]) -> bool
|
||||
|
||||
|
@ -991,6 +993,7 @@ class str:
|
|||
With optional start, test str beginning at that position.
|
||||
With optional end, stop comparing str at that position.
|
||||
"""
|
||||
end: int = end if end is not None else len(self)
|
||||
if end < 0:
|
||||
end += len(self)
|
||||
elif start < 0:
|
||||
|
@ -1015,12 +1018,13 @@ class str:
|
|||
|
||||
return suffix == self[start : start + len(suffix)]
|
||||
|
||||
def index(self, sub: str, start: int = 0, end: int = 0x7FFFFFFFFFFFFFFF) -> int:
|
||||
def index(self, sub: str, start: int = 0, end: Optional[int] = None) -> int:
|
||||
"""
|
||||
str.index(sub [,start [,end]]) -> int
|
||||
|
||||
Like str.find() but raise ValueError when the substring is not found.
|
||||
"""
|
||||
end: int = end if end is not None else len(self)
|
||||
start, end = self._correct_indices(start, end)
|
||||
i = self.find(sub, start, end)
|
||||
if i == -1:
|
||||
|
@ -1028,12 +1032,13 @@ class str:
|
|||
else:
|
||||
return i
|
||||
|
||||
def rindex(self, sub: str, start: int = 0, end: int = 0x7FFFFFFFFFFFFFFF) -> int:
|
||||
def rindex(self, sub: str, start: int = 0, end: Optional[int] = None) -> int:
|
||||
"""
|
||||
str.index(sub [,start [,end]]) -> int
|
||||
|
||||
Like str.find() but raise ValueError when the substring is not found.
|
||||
"""
|
||||
end: int = end if end is not None else len(self)
|
||||
start, end = self._correct_indices(start, end)
|
||||
i = self.rfind(sub, start, end)
|
||||
if i == -1:
|
||||
|
@ -1086,7 +1091,7 @@ class str:
|
|||
incr = 0
|
||||
i = 0 # chars up to and including most recent \n or \r
|
||||
j = 0 # chars since most recent \n or \r (use in tab calculations)
|
||||
u = List[str]()
|
||||
u = []
|
||||
j = 0 # same as first pass
|
||||
|
||||
# create output string and fill it
|
||||
|
@ -1147,7 +1152,7 @@ class str:
|
|||
if len(pattern) <= 5:
|
||||
yield from algorithms.string_search_slow(self, pattern)
|
||||
else:
|
||||
yield from algorithms.string_search_KMP(self, pattern)
|
||||
yield from algorithms.string_search_kmp(self, pattern)
|
||||
|
||||
def _rsearch(self, pattern: str) -> Generator[int]:
|
||||
if len(pattern) == 1:
|
||||
|
|
|
@ -11,8 +11,6 @@ def _dict_hash(key) -> int:
|
|||
|
||||
|
||||
class Dict:
|
||||
K: type
|
||||
V: type
|
||||
_n_buckets: int
|
||||
_size: int
|
||||
_n_occupied: int
|
||||
|
@ -22,9 +20,12 @@ class Dict:
|
|||
_keys: Ptr[K]
|
||||
_vals: Ptr[V]
|
||||
|
||||
K: type
|
||||
V: type
|
||||
|
||||
# Magic methods
|
||||
|
||||
def _init(self) -> void:
|
||||
def _init(self):
|
||||
self._n_buckets = 0
|
||||
self._size = 0
|
||||
self._n_occupied = 0
|
||||
|
@ -33,7 +34,7 @@ class Dict:
|
|||
self._keys = Ptr[K]()
|
||||
self._vals = Ptr[V]()
|
||||
|
||||
def _init_from(self, other) -> void:
|
||||
def _init_from(self, other):
|
||||
n = other._n_buckets
|
||||
|
||||
if n == 0:
|
||||
|
@ -57,15 +58,15 @@ class Dict:
|
|||
self._keys = keys_copy
|
||||
self._vals = vals_copy
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._init()
|
||||
|
||||
def __init__(self, g: Generator[Tuple[K, V]]) -> void:
|
||||
def __init__(self, g: Generator[Tuple[K, V]]):
|
||||
self._init()
|
||||
for k, v in g:
|
||||
self[k] = v
|
||||
|
||||
def __init__(self, other: Dict[K, V]) -> void:
|
||||
def __init__(self, other: Dict[K, V]):
|
||||
self._init_from(other)
|
||||
|
||||
def __getitem__(self, key: K) -> V:
|
||||
|
@ -74,11 +75,11 @@ class Dict:
|
|||
return self._vals[x]
|
||||
raise KeyError(str(key))
|
||||
|
||||
def __setitem__(self, key: K, val: V) -> void:
|
||||
def __setitem__(self, key: K, val: V):
|
||||
ret, x = self._kh_put(key)
|
||||
self._vals[x] = val
|
||||
|
||||
def __delitem__(self, key: K) -> void:
|
||||
def __delitem__(self, key: K):
|
||||
x = self._kh_get(key)
|
||||
if x != self._kh_end():
|
||||
self._kh_del(x)
|
||||
|
@ -134,7 +135,7 @@ class Dict:
|
|||
if n == 0:
|
||||
return "{}"
|
||||
else:
|
||||
lst = List[str]()
|
||||
lst = []
|
||||
lst.append("{")
|
||||
first = True
|
||||
for k, v in self.items():
|
||||
|
@ -150,7 +151,7 @@ class Dict:
|
|||
|
||||
# Helper methods
|
||||
|
||||
def resize(self, new_n_buckets: int) -> void:
|
||||
def resize(self, new_n_buckets: int):
|
||||
self._kh_resize(new_n_buckets)
|
||||
|
||||
def get(self, key: K, s: V) -> V:
|
||||
|
@ -164,25 +165,25 @@ class Dict:
|
|||
return val
|
||||
return self._vals[x]
|
||||
|
||||
def increment(self, key: K, by: T = 1, T: type) -> void:
|
||||
def increment(self, key: K, by: T = 1, T: type):
|
||||
ret, x = self._kh_put(key)
|
||||
if ret != 0: # i.e. key not present
|
||||
self._vals[x] = by
|
||||
else:
|
||||
self._vals[x] += by
|
||||
|
||||
def __dict_do_op_throws__(self, key: K, other: Z, op: F, F: type, Z: type) -> void:
|
||||
def __dict_do_op_throws__(self, key: K, other: Z, op: F, F: type, Z: type):
|
||||
x = self._kh_get(key)
|
||||
if x == self._kh_end():
|
||||
raise KeyError(str(key))
|
||||
else:
|
||||
self._vals[x] = op(self._vals[x], other)
|
||||
|
||||
def __dict_do_op__(self, key: K, other: Z, dflt: V, op: F, F: type, Z: type) -> void:
|
||||
def __dict_do_op__(self, key: K, other: Z, dflt: V, op: F, F: type, Z: type):
|
||||
ret, x = self._kh_put(key)
|
||||
self._vals[x] = op(dflt if ret != 0 else self._vals[x], other)
|
||||
|
||||
def update(self, other: Dict[K, V]) -> void:
|
||||
def update(self, other: Dict[K, V]):
|
||||
for k, v in other.items():
|
||||
self[k] = v
|
||||
|
||||
|
@ -199,7 +200,7 @@ class Dict:
|
|||
return (k, self.pop(k))
|
||||
raise KeyError("dictionary is empty")
|
||||
|
||||
def clear(self) -> void:
|
||||
def clear(self):
|
||||
self._kh_clear()
|
||||
|
||||
def items(self) -> Generator[Tuple[K, V]]:
|
||||
|
@ -225,7 +226,7 @@ class Dict:
|
|||
|
||||
# Internal helpers
|
||||
|
||||
def _kh_clear(self) -> void:
|
||||
def _kh_clear(self):
|
||||
if self._flags:
|
||||
i = 0
|
||||
n = khash.__ac_fsize(self._n_buckets)
|
||||
|
@ -253,7 +254,7 @@ class Dict:
|
|||
else:
|
||||
return 0
|
||||
|
||||
def _kh_resize(self, new_n_buckets: int) -> void:
|
||||
def _kh_resize(self, new_n_buckets: int):
|
||||
HASH_UPPER = 0.77
|
||||
new_flags = Ptr[u32]()
|
||||
j = 1
|
||||
|
@ -383,7 +384,7 @@ class Dict:
|
|||
|
||||
return (ret, x)
|
||||
|
||||
def _kh_del(self, x: int) -> void:
|
||||
def _kh_del(self, x: int):
|
||||
if x != self._n_buckets and not khash.__ac_iseither(self._flags, x):
|
||||
khash.__ac_set_isdel_true(self._flags, x)
|
||||
self._size -= 1
|
||||
|
|
|
@ -5,34 +5,34 @@ import internal.gc as gc
|
|||
|
||||
@extend
|
||||
class List:
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self.arr = Array[T](10)
|
||||
self.len = 0
|
||||
|
||||
def __init__(self, it: Generator[T]) -> void:
|
||||
def __init__(self, it: Generator[T]):
|
||||
self.arr = Array[T](10)
|
||||
self.len = 0
|
||||
for i in it:
|
||||
self.append(i)
|
||||
|
||||
def __init__(self, other: List[T]) -> void:
|
||||
def __init__(self, other: List[T]):
|
||||
self.arr = Array[T](other.len)
|
||||
self.len = 0
|
||||
for i in other:
|
||||
self.append(i)
|
||||
|
||||
def __init__(self, capacity: int) -> void:
|
||||
def __init__(self, capacity: int):
|
||||
self.arr = Array[T](capacity)
|
||||
self.len = 0
|
||||
|
||||
def __init__(self, dummy: bool, other) -> void:
|
||||
def __init__(self, dummy: bool, other):
|
||||
"""Dummy __init__ used for list comprehension optimization"""
|
||||
if hasattr(other, "__len__"):
|
||||
self.__init__(other.__len__())
|
||||
else:
|
||||
self.__init__()
|
||||
|
||||
def __init__(self, arr: Array[T], len: int) -> void:
|
||||
def __init__(self, arr: Array[T], len: int):
|
||||
self.arr = arr
|
||||
self.len = len
|
||||
|
||||
|
@ -48,13 +48,13 @@ class List:
|
|||
self._idx_check(idx, "list index out of range")
|
||||
return self.arr[idx]
|
||||
|
||||
def __setitem__(self, idx: int, val: T) -> void:
|
||||
def __setitem__(self, idx: int, val: T):
|
||||
if idx < 0:
|
||||
idx += self.__len__()
|
||||
self._idx_check(idx, "list assignment index out of range")
|
||||
self.arr[idx] = val
|
||||
|
||||
def __delitem__(self, idx: int) -> void:
|
||||
def __delitem__(self, idx: int):
|
||||
if idx < 0:
|
||||
idx += self.__len__()
|
||||
self._idx_check(idx, "list assignment index out of range")
|
||||
|
@ -87,7 +87,7 @@ class List:
|
|||
other.append(self.arr[i])
|
||||
return other
|
||||
|
||||
def __setitem__(self, s: Slice, other) -> void:
|
||||
def __setitem__(self, s: Slice, other):
|
||||
if s.start is None and s.stop is None and s.step is None:
|
||||
self.clear()
|
||||
for a in other:
|
||||
|
@ -132,7 +132,7 @@ class List:
|
|||
cur += step
|
||||
i += 1
|
||||
|
||||
def __delitem__(self, s: Slice) -> void:
|
||||
def __delitem__(self, s: Slice):
|
||||
if s.start is None and s.stop is None and s.step is None:
|
||||
self.clear()
|
||||
else:
|
||||
|
@ -268,16 +268,16 @@ class List:
|
|||
|
||||
# Helper functions
|
||||
|
||||
def append(self, x: T) -> void:
|
||||
def append(self, x: T):
|
||||
self._resize_if_full()
|
||||
self.arr[self.len] = x
|
||||
self.len += 1
|
||||
|
||||
def extend(self, itr: Generator[T]) -> void:
|
||||
def extend(self, itr: Generator[T]):
|
||||
for a in itr:
|
||||
self.append(a)
|
||||
|
||||
def insert(self, idx: int, x: T) -> void:
|
||||
def insert(self, idx: int, x: T):
|
||||
n = self.__len__()
|
||||
if idx < 0:
|
||||
idx += n
|
||||
|
@ -312,7 +312,7 @@ class List:
|
|||
i += 1
|
||||
return False
|
||||
|
||||
def clear(self) -> void:
|
||||
def clear(self):
|
||||
self.len = 0
|
||||
|
||||
def index(self, x: T) -> int:
|
||||
|
@ -330,7 +330,7 @@ class List:
|
|||
count += 1
|
||||
return count
|
||||
|
||||
def reverse(self) -> void:
|
||||
def reverse(self):
|
||||
i = 0
|
||||
while i < self.len // 2:
|
||||
j = self.len - i - 1
|
||||
|
@ -344,15 +344,15 @@ class List:
|
|||
|
||||
# Internal helpers
|
||||
|
||||
def _idx_check(self, idx: int, msg: str) -> void:
|
||||
def _idx_check(self, idx: int, msg: str):
|
||||
if idx >= self.len or idx < 0:
|
||||
raise IndexError(msg)
|
||||
|
||||
def _resize(self, new_cap: int) -> void:
|
||||
def _resize(self, new_cap: int):
|
||||
p = Ptr[T](gc.realloc(self.arr.ptr.as_byte(), new_cap * gc.sizeof(T)))
|
||||
self.arr = Array[T](p, new_cap)
|
||||
|
||||
def _resize_if_full(self) -> void:
|
||||
def _resize_if_full(self):
|
||||
if self.len == self.arr.len:
|
||||
new_cap = (1 + 3 * self.len) // 2
|
||||
self._resize(new_cap)
|
||||
|
@ -364,7 +364,7 @@ class List:
|
|||
seed ^= v.__hash__() + 0x9E3779B9 + (seed << 6) + (seed >> 2)
|
||||
return seed
|
||||
|
||||
def _assign_slice(self, ilow: int, ihigh: int, v: Ptr[T], n: int) -> void:
|
||||
def _assign_slice(self, ilow: int, ihigh: int, v: Ptr[T], n: int):
|
||||
a = self
|
||||
L = a.len
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ def _set_hash(key) -> int:
|
|||
|
||||
|
||||
class Set:
|
||||
K: type
|
||||
_n_buckets: int
|
||||
_size: int
|
||||
_n_occupied: int
|
||||
|
@ -21,8 +20,10 @@ class Set:
|
|||
_flags: Ptr[u32]
|
||||
_keys: Ptr[K]
|
||||
|
||||
K: type
|
||||
|
||||
# Magic methods
|
||||
def _init(self) -> void:
|
||||
def _init(self):
|
||||
self._n_buckets = 0
|
||||
self._size = 0
|
||||
self._n_occupied = 0
|
||||
|
@ -30,10 +31,10 @@ class Set:
|
|||
self._flags = Ptr[u32]()
|
||||
self._keys = Ptr[K]()
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._init()
|
||||
|
||||
def __init__(self, g: Generator[K]) -> void:
|
||||
def __init__(self, g: Generator[K]):
|
||||
self._init()
|
||||
for a in g:
|
||||
self.add(a)
|
||||
|
@ -133,7 +134,7 @@ class Set:
|
|||
if n == 0:
|
||||
return "{}"
|
||||
else:
|
||||
lst = List[str]()
|
||||
lst = []
|
||||
lst.append("{")
|
||||
first = True
|
||||
for k in self:
|
||||
|
@ -147,17 +148,17 @@ class Set:
|
|||
|
||||
# Helper methods
|
||||
|
||||
def resize(self, new_n_buckets: int) -> void:
|
||||
def resize(self, new_n_buckets: int):
|
||||
self._kh_resize(new_n_buckets)
|
||||
|
||||
def add(self, key: K) -> void:
|
||||
def add(self, key: K):
|
||||
self._kh_put(key)
|
||||
|
||||
def update(self, other: Set[K]) -> void:
|
||||
def update(self, other: Set[K]):
|
||||
for k in other:
|
||||
self.add(k)
|
||||
|
||||
def remove(self, key: K) -> void:
|
||||
def remove(self, key: K):
|
||||
x = self._kh_get(key)
|
||||
if x != self._kh_end():
|
||||
self._kh_del(x)
|
||||
|
@ -171,7 +172,7 @@ class Set:
|
|||
self.remove(a)
|
||||
return a
|
||||
|
||||
def discard(self, key: K) -> void:
|
||||
def discard(self, key: K):
|
||||
x = self._kh_get(key)
|
||||
if x != self._kh_end():
|
||||
self._kh_del(x)
|
||||
|
@ -183,7 +184,7 @@ class Set:
|
|||
s.add(a)
|
||||
return s
|
||||
|
||||
def difference_update(self, other: Set[K]) -> void:
|
||||
def difference_update(self, other: Set[K]):
|
||||
for a in other:
|
||||
self.discard(a)
|
||||
|
||||
|
@ -196,7 +197,7 @@ class Set:
|
|||
s.add(a)
|
||||
return s
|
||||
|
||||
def intersection_update(self, other: Set[K]) -> void:
|
||||
def intersection_update(self, other: Set[K]):
|
||||
for a in self:
|
||||
if a not in other:
|
||||
self.discard(a)
|
||||
|
@ -211,7 +212,7 @@ class Set:
|
|||
s.add(a)
|
||||
return s
|
||||
|
||||
def symmetric_difference_update(self, other: Set[K]) -> void:
|
||||
def symmetric_difference_update(self, other: Set[K]):
|
||||
for a in other:
|
||||
if a in self:
|
||||
self.discard(a)
|
||||
|
@ -249,7 +250,7 @@ class Set:
|
|||
def issuperset(self, other: Set[K]) -> bool:
|
||||
return other.issubset(self)
|
||||
|
||||
def clear(self) -> void:
|
||||
def clear(self):
|
||||
self._kh_clear()
|
||||
|
||||
def copy(self) -> Set[K]:
|
||||
|
@ -257,7 +258,7 @@ class Set:
|
|||
|
||||
# Internal helpers
|
||||
|
||||
def _kh_clear(self) -> void:
|
||||
def _kh_clear(self):
|
||||
if self._flags:
|
||||
i = 0
|
||||
n = khash.__ac_fsize(self._n_buckets)
|
||||
|
@ -285,7 +286,7 @@ class Set:
|
|||
else:
|
||||
return 0
|
||||
|
||||
def _kh_resize(self, new_n_buckets: int) -> void:
|
||||
def _kh_resize(self, new_n_buckets: int):
|
||||
HASH_UPPER = 0.77
|
||||
new_flags = Ptr[u32]()
|
||||
j = 1
|
||||
|
@ -406,7 +407,7 @@ class Set:
|
|||
|
||||
return (ret, x)
|
||||
|
||||
def _kh_del(self, x: int) -> void:
|
||||
def _kh_del(self, x: int):
|
||||
if x != self._n_buckets and not khash.__ac_iseither(self._flags, x):
|
||||
khash.__ac_set_isdel_true(self._flags, x)
|
||||
self._size -= 1
|
||||
|
|
|
@ -16,10 +16,10 @@ class ExcHeader:
|
|||
class OSError:
|
||||
_hdr: ExcHeader
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._hdr = ("OSError", "", "", "", 0, 0)
|
||||
|
||||
def __init__(self, message: str) -> void:
|
||||
def __init__(self, message: str):
|
||||
self._hdr = ("OSError", message, "", "", 0, 0)
|
||||
|
||||
@property
|
||||
|
@ -30,10 +30,10 @@ class OSError:
|
|||
class IOError:
|
||||
_hdr: ExcHeader
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._hdr = ("IOError", "", "", "", 0, 0)
|
||||
|
||||
def __init__(self, message: str) -> void:
|
||||
def __init__(self, message: str):
|
||||
self._hdr = ("IOError", message, "", "", 0, 0)
|
||||
|
||||
@property
|
||||
|
@ -44,10 +44,10 @@ class IOError:
|
|||
class ValueError:
|
||||
_hdr: ExcHeader
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._hdr = ("ValueError", "", "", "", 0, 0)
|
||||
|
||||
def __init__(self, message: str) -> void:
|
||||
def __init__(self, message: str):
|
||||
self._hdr = ("ValueError", message, "", "", 0, 0)
|
||||
|
||||
@property
|
||||
|
@ -58,10 +58,10 @@ class ValueError:
|
|||
class IndexError:
|
||||
_hdr: ExcHeader
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._hdr = ("IndexError", "", "", "", 0, 0)
|
||||
|
||||
def __init__(self, message: str) -> void:
|
||||
def __init__(self, message: str):
|
||||
self._hdr = ("IndexError", message, "", "", 0, 0)
|
||||
|
||||
@property
|
||||
|
@ -72,10 +72,10 @@ class IndexError:
|
|||
class KeyError:
|
||||
_hdr: ExcHeader
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._hdr = ("KeyError", "", "", "", 0, 0)
|
||||
|
||||
def __init__(self, message: str) -> void:
|
||||
def __init__(self, message: str):
|
||||
self._hdr = ("KeyError", message, "", "", 0, 0)
|
||||
|
||||
@property
|
||||
|
@ -86,10 +86,10 @@ class KeyError:
|
|||
class OverflowError:
|
||||
_hdr: ExcHeader
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._hdr = ("OverflowError", "", "", "", 0, 0)
|
||||
|
||||
def __init__(self, message: str) -> void:
|
||||
def __init__(self, message: str):
|
||||
self._hdr = ("OverflowError", message, "", "", 0, 0)
|
||||
|
||||
@property
|
||||
|
@ -100,10 +100,10 @@ class OverflowError:
|
|||
class CError:
|
||||
_hdr: ExcHeader
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._hdr = ("CError", "", "", "", 0, 0)
|
||||
|
||||
def __init__(self, message: str) -> void:
|
||||
def __init__(self, message: str):
|
||||
self._hdr = ("CError", message, "", "", 0, 0)
|
||||
|
||||
@property
|
||||
|
@ -115,7 +115,7 @@ class PyError:
|
|||
_hdr: ExcHeader
|
||||
pytype: str
|
||||
|
||||
def __init__(self, message: str, pytype: str) -> void:
|
||||
def __init__(self, message: str, pytype: str):
|
||||
self._hdr = ("PyError", message, "", "", 0, 0)
|
||||
self.pytype = pytype
|
||||
|
||||
|
@ -127,10 +127,10 @@ class PyError:
|
|||
class TypeError:
|
||||
_hdr: ExcHeader
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._hdr = ("TypeError", "", "", "", 0, 0)
|
||||
|
||||
def __init__(self, message: str) -> void:
|
||||
def __init__(self, message: str):
|
||||
self._hdr = ("TypeError", message, "", "", 0, 0)
|
||||
|
||||
@property
|
||||
|
@ -141,10 +141,10 @@ class TypeError:
|
|||
class ZeroDivisionError:
|
||||
_hdr: ExcHeader
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._hdr = ("ZeroDivisionError", "", "", "", 0, 0)
|
||||
|
||||
def __init__(self, message: str) -> void:
|
||||
def __init__(self, message: str):
|
||||
self._hdr = ("ZeroDivisionError", message, "", "", 0, 0)
|
||||
|
||||
@property
|
||||
|
@ -155,10 +155,10 @@ class ZeroDivisionError:
|
|||
class AttributeError:
|
||||
_hdr: ExcHeader
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._hdr = ("AttributeError", "", "", "", 0, 0)
|
||||
|
||||
def __init__(self, message: str) -> void:
|
||||
def __init__(self, message: str):
|
||||
self._hdr = ("AttributeError", message, "", "", 0, 0)
|
||||
|
||||
@property
|
||||
|
@ -169,10 +169,10 @@ class AttributeError:
|
|||
class NotImplementedError:
|
||||
_hdr: ExcHeader
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._hdr = ("NotImplementedError", "", "", "", 0, 0)
|
||||
|
||||
def __init__(self, message: str) -> void:
|
||||
def __init__(self, message: str):
|
||||
self._hdr = ("NotImplementedError", message, "", "", 0, 0)
|
||||
|
||||
@property
|
||||
|
@ -183,10 +183,10 @@ class NotImplementedError:
|
|||
class StopIteration:
|
||||
_hdr: ExcHeader
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._hdr = ("StopIteration", "", "", "", 0, 0)
|
||||
|
||||
def __init__(self, message: str) -> void:
|
||||
def __init__(self, message: str):
|
||||
self._hdr = ("StopIteration", message, "", "", 0, 0)
|
||||
|
||||
@property
|
||||
|
@ -197,10 +197,10 @@ class StopIteration:
|
|||
class AssertionError:
|
||||
_hdr: ExcHeader
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._hdr = ("AssertionError", "", "", "", 0, 0)
|
||||
|
||||
def __init__(self, message: str) -> void:
|
||||
def __init__(self, message: str):
|
||||
self._hdr = ("AssertionError", message, "", "", 0, 0)
|
||||
|
||||
@property
|
||||
|
@ -212,19 +212,19 @@ class SystemExit:
|
|||
_hdr: ExcHeader
|
||||
_status: int
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._hdr = ("SystemExit", "", "", "", 0, 0)
|
||||
self._status = 0
|
||||
|
||||
def __init__(self, status: int) -> void:
|
||||
def __init__(self, status: int):
|
||||
self._hdr = ("SystemExit", "", "", "", 0, 0)
|
||||
self._status = status
|
||||
|
||||
def __init__(self, message: str) -> void:
|
||||
def __init__(self, message: str):
|
||||
self._hdr = ("SystemExit", message, "", "", 0, 0)
|
||||
self._status = 0
|
||||
|
||||
def __init__(self, message: str, status: int) -> void:
|
||||
def __init__(self, message: str, status: int):
|
||||
self._hdr = ("SystemExit", message, "", "", 0, 0)
|
||||
self._status = status
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ class float:
|
|||
free(p)
|
||||
|
||||
if end != p + n:
|
||||
raise ValueError("could not convert string to float: " + s)
|
||||
raise ValueError(f"could not convert string to float: {s}")
|
||||
|
||||
return result
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
from internal.attributes import commutative, associative, distributive
|
||||
|
||||
|
||||
def check_N(N: Static[int]) -> void:
|
||||
def check_N(N: Static[int]):
|
||||
if N <= 0:
|
||||
compile_error("N must be greater than 0")
|
||||
pass
|
||||
|
|
|
@ -43,6 +43,6 @@ optional = Optional
|
|||
|
||||
|
||||
def unwrap(opt: Optional[T], T: type) -> T:
|
||||
if not opt:
|
||||
if opt is None:
|
||||
raise ValueError("optional is None")
|
||||
return ~opt
|
||||
|
|
|
@ -192,15 +192,15 @@ cobj = Ptr[byte]
|
|||
@__internal__
|
||||
@tuple
|
||||
class Array:
|
||||
T: type
|
||||
len: int
|
||||
ptr: Ptr[T]
|
||||
T: type
|
||||
|
||||
|
||||
class List:
|
||||
T: type
|
||||
arr: Array[T]
|
||||
len: int
|
||||
arr: Array[T]
|
||||
T: type
|
||||
|
||||
|
||||
@extend
|
||||
|
|
|
@ -92,14 +92,6 @@ class range:
|
|||
|
||||
def __repr__(self) -> str:
|
||||
if self.step == 1:
|
||||
return "range(" + str(self.start) + ", " + str(self.stop) + ")"
|
||||
return f"range({self.start}, {self.stop})"
|
||||
else:
|
||||
return (
|
||||
"range("
|
||||
+ str(self.start)
|
||||
+ ", "
|
||||
+ str(self.stop)
|
||||
+ ", "
|
||||
+ str(self.step)
|
||||
+ ")"
|
||||
)
|
||||
return f"range({self.start}, {self.stop}, {self.step})"
|
||||
|
|
|
@ -8,18 +8,18 @@ class Slice:
|
|||
step: Optional[int]
|
||||
|
||||
def adjust_indices(self, length: int) -> Tuple[int, int, int, int]:
|
||||
stepx = ~self.step if self.step else 1
|
||||
startx = 0
|
||||
stopx = 0
|
||||
if stepx == 0:
|
||||
step: int = self.step if self.step else 1
|
||||
start: int = 0
|
||||
stop: int = 0
|
||||
if step == 0:
|
||||
raise ValueError("slice step cannot be zero")
|
||||
if stepx > 0:
|
||||
startx = ~self.start if self.start else 0
|
||||
stopx = ~self.stop if self.stop else length
|
||||
if step > 0:
|
||||
start = self.start if self.start else 0
|
||||
stop = self.stop if self.stop else length
|
||||
else:
|
||||
startx = ~self.start if self.start else length - 1
|
||||
stopx = ~self.stop if self.stop else -(length + 1)
|
||||
return Slice.adjust_indices_helper(length, startx, stopx, stepx)
|
||||
start = self.start if self.start else length - 1
|
||||
stop = self.stop if self.stop else -(length + 1)
|
||||
return Slice.adjust_indices_helper(length, start, stop, step)
|
||||
|
||||
def adjust_indices_helper(
|
||||
length: int, start: int, stop: int, step: int
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# (c) 2022 Exaloop Inc. All rights reserved.
|
||||
|
||||
from internal.types.optional import unwrap
|
||||
|
||||
# Infinite iterators
|
||||
|
||||
|
||||
|
@ -46,13 +48,12 @@ def repeat(object: T, times: Optional[int] = None, T: type) -> Generator[T]:
|
|||
|
||||
@tuple
|
||||
class accumulate:
|
||||
"""
|
||||
Make an iterator that returns accumulated sums, or accumulated results
|
||||
of other binary functions (specified via the optional func argument).
|
||||
"""
|
||||
|
||||
@inline
|
||||
def __new__(iterable: Generator[T], func=lambda a, b: a + b, initial=0, T: type):
|
||||
"""
|
||||
Make an iterator that returns accumulated sums, or accumulated results
|
||||
of other binary functions (specified via the optional func argument).
|
||||
"""
|
||||
total = initial
|
||||
yield total
|
||||
for element in iterable:
|
||||
|
@ -61,10 +62,14 @@ class accumulate:
|
|||
|
||||
@inline
|
||||
def __new__(iterable: Generator[T], func=lambda a, b: a + b, T: type):
|
||||
"""
|
||||
Make an iterator that returns accumulated sums, or accumulated results
|
||||
of other binary functions (specified via the optional func argument).
|
||||
"""
|
||||
total = None
|
||||
for element in iterable:
|
||||
total = element if total is None else func(~total, element)
|
||||
yield ~total
|
||||
total = element if total is None else func(unwrap(total), element)
|
||||
yield unwrap(total)
|
||||
|
||||
|
||||
@tuple
|
||||
|
@ -142,29 +147,28 @@ def groupby(iterable, key=Optional[int]()):
|
|||
k = currvalue if isinstance(key, Optional) else key(currvalue)
|
||||
if currkey is None:
|
||||
currkey = k
|
||||
if k != ~currkey:
|
||||
yield ~currkey, group
|
||||
if k != unwrap(currkey):
|
||||
yield unwrap(currkey), group
|
||||
currkey = k
|
||||
group = []
|
||||
group.append(currvalue)
|
||||
if currkey is not None:
|
||||
yield ~currkey, group
|
||||
yield unwrap(currkey), group
|
||||
|
||||
|
||||
@tuple
|
||||
class islice:
|
||||
"""
|
||||
Make an iterator that returns selected elements from the iterable.
|
||||
"""
|
||||
|
||||
def __new__(iterable: Generator[T], stop: Optional[int], T: type) -> Generator[T]:
|
||||
if stop and ~stop < 0:
|
||||
"""
|
||||
Make an iterator that returns selected elements from the iterable.
|
||||
"""
|
||||
if stop and unwrap(stop) < 0:
|
||||
raise ValueError(
|
||||
"Indices for islice() must be None or an integer: 0 <= x <= sys.maxsize."
|
||||
)
|
||||
i = 0
|
||||
for x in iterable:
|
||||
if stop and i >= ~stop:
|
||||
if stop and i >= unwrap(stop):
|
||||
break
|
||||
yield x
|
||||
i += 1
|
||||
|
@ -176,11 +180,14 @@ class islice:
|
|||
step: Optional[int] = None,
|
||||
T: type,
|
||||
) -> Generator[T]:
|
||||
"""
|
||||
Make an iterator that returns selected elements from the iterable.
|
||||
"""
|
||||
from sys import maxsize
|
||||
|
||||
start: int = 0 if not start else ~start
|
||||
stop: int = maxsize if not stop else ~stop
|
||||
step: int = 1 if not step else ~step
|
||||
start: int = 0 if not start else start
|
||||
stop: int = maxsize if not stop else stop
|
||||
step: int = 1 if not step else step
|
||||
have_stop = False
|
||||
|
||||
if start < 0 or stop < 0:
|
||||
|
@ -266,15 +273,14 @@ def tee(iterable: Generator[T], n: int = 2, T: type) -> List[Generator[T]]:
|
|||
|
||||
@tuple
|
||||
class zip_longest:
|
||||
"""
|
||||
Make an iterator that aggregates elements from each of the iterables.
|
||||
If the iterables are of uneven length, missing values are filled-in
|
||||
with fillvalue. Iteration continues until the longest iterable is
|
||||
exhausted.
|
||||
"""
|
||||
|
||||
@inline
|
||||
def __new__(*iterables, fillvalue):
|
||||
"""
|
||||
Make an iterator that aggregates elements from each of the iterables.
|
||||
If the iterables are of uneven length, missing values are filled-in
|
||||
with fillvalue. Iteration continues until the longest iterable is
|
||||
exhausted.
|
||||
"""
|
||||
if staticlen(iterables) == 2:
|
||||
a = iter(iterables[0])
|
||||
b = iter(iterables[1])
|
||||
|
@ -317,6 +323,13 @@ class zip_longest:
|
|||
|
||||
@inline
|
||||
def __new__(*args):
|
||||
"""
|
||||
Make an iterator that aggregates elements from each of the iterables.
|
||||
If the iterables are of uneven length, missing values are filled-in
|
||||
with fillvalue. Iteration continues until the longest iterable is
|
||||
exhausted.
|
||||
"""
|
||||
|
||||
def get_next(it):
|
||||
if it.__done__() or it.done():
|
||||
return None
|
||||
|
@ -422,7 +435,7 @@ def permutations(
|
|||
pool: List[T], r: Optional[int], T: type
|
||||
) -> Generator[List[T]]:
|
||||
n = len(pool)
|
||||
r: int = ~r if r else n
|
||||
r: int = r if r else n
|
||||
if r > n:
|
||||
return
|
||||
|
||||
|
@ -445,7 +458,7 @@ def permutations(
|
|||
if b == -1:
|
||||
return
|
||||
|
||||
if r is not None and ~r < 0:
|
||||
if r is not None and unwrap(r) < 0:
|
||||
raise ValueError("r must be non-negative")
|
||||
if hasattr(pool, "__getitem__") and hasattr(pool, "__len__"):
|
||||
return permutations_helper(pool, r)
|
||||
|
@ -455,12 +468,11 @@ def permutations(
|
|||
|
||||
@tuple
|
||||
class product:
|
||||
"""
|
||||
Cartesian product of input iterables.
|
||||
"""
|
||||
|
||||
@inline
|
||||
def __new__(*args):
|
||||
"""
|
||||
Cartesian product of input iterables.
|
||||
"""
|
||||
if staticlen(args) == 0:
|
||||
yield ()
|
||||
else:
|
||||
|
@ -471,6 +483,9 @@ class product:
|
|||
|
||||
@inline
|
||||
def __new__(*args, repeat: int):
|
||||
"""
|
||||
Cartesian product of input iterables.
|
||||
"""
|
||||
if repeat < 0:
|
||||
raise ValueError("repeat argument cannot be negative")
|
||||
pools = [list(pool) for _ in range(repeat) for pool in args]
|
||||
|
|
|
@ -70,9 +70,9 @@ class Task:
|
|||
|
||||
@tuple
|
||||
class TaskWithPrivates:
|
||||
T: type
|
||||
task: Task
|
||||
data: T
|
||||
T: type
|
||||
|
||||
|
||||
_DEFAULT_IDENT = Ident()
|
||||
|
@ -846,7 +846,7 @@ def _atomic_float_min(a: Ptr[float], b: float):
|
|||
__kmpc_atomic_float8_min(_default_loc(), i32(get_thread_num()), a, b)
|
||||
|
||||
|
||||
def _atomic_float_max(a: Ptr[float], b: float) -> void:
|
||||
def _atomic_float_max(a: Ptr[float], b: float):
|
||||
from C import __kmpc_atomic_float8_max(Ptr[Ident], i32, Ptr[float], float)
|
||||
__kmpc_atomic_float8_max(_default_loc(), i32(get_thread_num()), a, b)
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ class EnvMap:
|
|||
def __new__() -> EnvMap:
|
||||
return (Dict[str, str](),)
|
||||
|
||||
def _init_if_needed(self) -> void:
|
||||
def _init_if_needed(self):
|
||||
if len(self._map) == 0:
|
||||
env = _C.seq_env()
|
||||
p = env[0]
|
||||
|
|
|
@ -4,7 +4,7 @@ from internal.file import _gz_errcheck
|
|||
from internal.gc import sizeof, atomic
|
||||
|
||||
|
||||
def pickle(x: T, jar: Jar, T: type) -> void:
|
||||
def pickle(x: T, jar: Jar, T: type):
|
||||
x.__pickle__(jar)
|
||||
|
||||
|
||||
|
@ -12,7 +12,7 @@ def unpickle(jar: Jar, T: type) -> T:
|
|||
return T.__unpickle__(jar)
|
||||
|
||||
|
||||
def dump(x: T, f, T: type) -> void:
|
||||
def dump(x: T, f, T: type):
|
||||
x.__pickle__(f.fp)
|
||||
|
||||
|
||||
|
@ -20,31 +20,31 @@ def load(f, T: type) -> T:
|
|||
return T.__unpickle__(f.fp)
|
||||
|
||||
|
||||
def _write_raw(jar: Jar, p: cobj, n: int) -> void:
|
||||
def _write_raw(jar: Jar, p: cobj, n: int):
|
||||
LIMIT = 0x7FFFFFFF
|
||||
while n > 0:
|
||||
b = n if n < LIMIT else LIMIT
|
||||
status = int(_C.gzwrite(jar, p, u32(b)))
|
||||
if status != b:
|
||||
_gz_errcheck(jar)
|
||||
raise IOError("pickle error: gzwrite returned " + str(status))
|
||||
raise IOError(f"pickle error: gzwrite returned {status}")
|
||||
p += b
|
||||
n -= b
|
||||
|
||||
|
||||
def _read_raw(jar: Jar, p: cobj, n: int) -> void:
|
||||
def _read_raw(jar: Jar, p: cobj, n: int):
|
||||
LIMIT = 0x7FFFFFFF
|
||||
while n > 0:
|
||||
b = n if n < LIMIT else LIMIT
|
||||
status = int(_C.gzread(jar, p, u32(b)))
|
||||
if status != b:
|
||||
_gz_errcheck(jar)
|
||||
raise IOError("pickle error: gzread returned " + str(status))
|
||||
raise IOError(f"pickle error: gzread returned {status}")
|
||||
p += b
|
||||
n -= b
|
||||
|
||||
|
||||
def _write(jar: Jar, x: T, T: type) -> void:
|
||||
def _write(jar: Jar, x: T, T: type):
|
||||
y = __ptr__(x)
|
||||
_write_raw(jar, y.as_byte(), sizeof(T))
|
||||
|
||||
|
@ -61,7 +61,7 @@ def _read(jar: Jar, T: type) -> T:
|
|||
|
||||
@extend
|
||||
class int:
|
||||
def __pickle__(self, jar: Jar) -> void:
|
||||
def __pickle__(self, jar: Jar):
|
||||
_write(jar, self)
|
||||
|
||||
def __unpickle__(jar: Jar) -> int:
|
||||
|
@ -70,7 +70,7 @@ class int:
|
|||
|
||||
@extend
|
||||
class float:
|
||||
def __pickle__(self, jar: Jar) -> void:
|
||||
def __pickle__(self, jar: Jar):
|
||||
_write(jar, self)
|
||||
|
||||
def __unpickle__(jar: Jar) -> float:
|
||||
|
@ -79,7 +79,7 @@ class float:
|
|||
|
||||
@extend
|
||||
class bool:
|
||||
def __pickle__(self, jar: Jar) -> void:
|
||||
def __pickle__(self, jar: Jar):
|
||||
_write(jar, self)
|
||||
|
||||
def __unpickle__(jar: Jar) -> bool:
|
||||
|
@ -88,7 +88,7 @@ class bool:
|
|||
|
||||
@extend
|
||||
class byte:
|
||||
def __pickle__(self, jar: Jar) -> void:
|
||||
def __pickle__(self, jar: Jar):
|
||||
_write(jar, self)
|
||||
|
||||
def __unpickle__(jar: Jar) -> byte:
|
||||
|
@ -97,7 +97,7 @@ class byte:
|
|||
|
||||
@extend
|
||||
class str:
|
||||
def __pickle__(self, jar: Jar) -> void:
|
||||
def __pickle__(self, jar: Jar):
|
||||
_write(jar, self.len)
|
||||
_write_raw(jar, self.ptr, self.len)
|
||||
|
||||
|
@ -110,7 +110,7 @@ class str:
|
|||
|
||||
@extend
|
||||
class List:
|
||||
def __pickle__(self, jar: Jar) -> void:
|
||||
def __pickle__(self, jar: Jar):
|
||||
n = len(self)
|
||||
pickle(n, jar)
|
||||
if atomic(T):
|
||||
|
@ -132,7 +132,7 @@ class List:
|
|||
|
||||
@extend
|
||||
class Dict:
|
||||
def __pickle__(self, jar: Jar) -> void:
|
||||
def __pickle__(self, jar: Jar):
|
||||
import internal.khash as khash
|
||||
|
||||
if atomic(K) and atomic(V):
|
||||
|
@ -156,7 +156,7 @@ class Dict:
|
|||
def __unpickle__(jar: Jar) -> Dict[K, V]:
|
||||
import internal.khash as khash
|
||||
|
||||
d = Dict[K, V]()
|
||||
d = {}
|
||||
if atomic(K) and atomic(V):
|
||||
n_buckets = unpickle(jar, int)
|
||||
size = unpickle(jar, int)
|
||||
|
@ -192,7 +192,7 @@ class Dict:
|
|||
|
||||
@extend
|
||||
class Set:
|
||||
def __pickle__(self, jar: Jar) -> void:
|
||||
def __pickle__(self, jar: Jar):
|
||||
import internal.khash as khash
|
||||
|
||||
if atomic(K):
|
||||
|
@ -214,7 +214,7 @@ class Set:
|
|||
def __unpickle__(jar: Jar) -> Set[K]:
|
||||
import internal.khash as khash
|
||||
|
||||
s = Set[K]()
|
||||
s = set[K]()
|
||||
if atomic(K):
|
||||
n_buckets = unpickle(jar, int)
|
||||
size = unpickle(jar, int)
|
||||
|
|
|
@ -35,7 +35,7 @@ class RandomGenerator:
|
|||
|
||||
def init_genrand(self, s: u32):
|
||||
"""
|
||||
init_genrand(u32) -> void
|
||||
init_genrand(u32)
|
||||
|
||||
initializes state[N] with a seed
|
||||
"""
|
||||
|
@ -226,7 +226,7 @@ class Random:
|
|||
|
||||
def getstate(self):
|
||||
return self.gen.getstate()
|
||||
|
||||
|
||||
def setstate(self, state):
|
||||
self.gen.setstate(state)
|
||||
|
||||
|
|
|
@ -8,23 +8,21 @@ DEFAULT_LOAD_FACTOR = 1000
|
|||
|
||||
|
||||
class SortedList:
|
||||
T: type
|
||||
_len: int
|
||||
_load: int
|
||||
_lists: List[List[T]]
|
||||
_maxes: List[T]
|
||||
_offset: int
|
||||
# _index:
|
||||
T: type
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self._len = 0
|
||||
self._load = DEFAULT_LOAD_FACTOR
|
||||
self._lists = List[List[T]]()
|
||||
self._maxes = List[T]()
|
||||
# self._index = []
|
||||
self._lists = []
|
||||
self._maxes = []
|
||||
self._offset = 0
|
||||
|
||||
def clear(self) -> void:
|
||||
def clear(self):
|
||||
"""
|
||||
Remove all values from sorted list.
|
||||
Runtime complexity: `O(n)`
|
||||
|
@ -33,7 +31,6 @@ class SortedList:
|
|||
self._lists.clear()
|
||||
self._maxes.clear()
|
||||
self._offset = 0
|
||||
# self._index.clear()
|
||||
|
||||
@property
|
||||
def left(self) -> T:
|
||||
|
@ -41,7 +38,7 @@ class SortedList:
|
|||
raise IndexError("list index out of range")
|
||||
return self._lists[0][0]
|
||||
|
||||
def add(self, value: T) -> void:
|
||||
def add(self, value: T):
|
||||
"""
|
||||
Add `value` to sorted list.
|
||||
Runtime complexity: `O(log(n))` -- approximate.
|
||||
|
@ -67,7 +64,7 @@ class SortedList:
|
|||
self._maxes.append(value)
|
||||
self._len += 1
|
||||
|
||||
def _expand(self, pos: int) -> void:
|
||||
def _expand(self, pos: int):
|
||||
"""
|
||||
Split sublists with length greater than double the load-factor.
|
||||
Updates the index when the sublist length is less than double the load
|
||||
|
@ -86,7 +83,7 @@ class SortedList:
|
|||
self._lists.insert(pos + 1, half)
|
||||
_maxes.insert(pos + 1, half[-1])
|
||||
|
||||
def _delete(self, pos: int, idx: int) -> void:
|
||||
def _delete(self, pos: int, idx: int):
|
||||
"""
|
||||
Delete value at the given `(pos, idx)`.
|
||||
Combines lists that are less than half the load level.
|
||||
|
|
|
@ -147,12 +147,12 @@ def multimode(data: List[T], T: type):
|
|||
elem = data[0]
|
||||
counter = data.count(elem)
|
||||
li = sorted(data)
|
||||
mulmode = List[T]()
|
||||
mulmode = []
|
||||
|
||||
for i in li:
|
||||
curr_frequency = data.count(i)
|
||||
if curr_frequency > counter:
|
||||
mulmode = List[T]()
|
||||
mulmode = []
|
||||
mulmode.append(i)
|
||||
counter = curr_frequency
|
||||
elif curr_frequency == counter and i not in mulmode:
|
||||
|
@ -188,7 +188,7 @@ def quantiles(
|
|||
|
||||
if method == "inclusive":
|
||||
m = ld - 1
|
||||
result = List[float]()
|
||||
result = []
|
||||
for i in range(1, n):
|
||||
j = i * m // n
|
||||
delta = (i * m) - (j * n)
|
||||
|
@ -197,7 +197,7 @@ def quantiles(
|
|||
return result
|
||||
if method == "exclusive":
|
||||
m = ld + 1
|
||||
result = List[float]()
|
||||
result = []
|
||||
for i in range(1, n):
|
||||
j = i * m // n # rescale i to m/n
|
||||
j = 1 if j < 1 else ld - 1 if j > ld - 1 else j # clamp to 1 .. ld-1
|
||||
|
@ -510,55 +510,22 @@ class NormalDist:
|
|||
if _fabs(q) <= 0.425:
|
||||
r = 0.180625 - q * q
|
||||
# Hash sum: 55.88319_28806_14901_4439
|
||||
num = (
|
||||
(
|
||||
(
|
||||
(
|
||||
(
|
||||
(
|
||||
(
|
||||
2.5090809287301226727e3 * r
|
||||
+ 3.3430575583588128105e4
|
||||
)
|
||||
* r
|
||||
+ 6.7265770927008700853e4
|
||||
)
|
||||
* r
|
||||
+ 4.5921953931549871457e4
|
||||
)
|
||||
* r
|
||||
+ 1.3731693765509461125e4
|
||||
)
|
||||
* r
|
||||
+ 1.9715909503065514427e3
|
||||
)
|
||||
* r
|
||||
+ 1.3314166789178437745e2
|
||||
)
|
||||
* r
|
||||
+ 3.3871328727963666080e0
|
||||
) * q
|
||||
den = (
|
||||
(
|
||||
(
|
||||
(
|
||||
(
|
||||
(5.2264952788528545610e3 * r + 2.8729085735721942674e4)
|
||||
* r
|
||||
+ 3.9307895800092710610e4
|
||||
)
|
||||
* r
|
||||
+ 2.1213794301586595867e4
|
||||
)
|
||||
* r
|
||||
+ 5.3941960214247511077e3
|
||||
)
|
||||
* r
|
||||
+ 6.8718700749205790830e2
|
||||
)
|
||||
* r
|
||||
+ 4.2313330701600911252e1
|
||||
) * r + 1.0
|
||||
num = (((((((2.5090809287301226727e+3 * r +
|
||||
3.3430575583588128105e+4) * r +
|
||||
6.7265770927008700853e+4) * r +
|
||||
4.5921953931549871457e+4) * r +
|
||||
1.3731693765509461125e+4) * r +
|
||||
1.9715909503065514427e+3) * r +
|
||||
1.3314166789178437745e+2) * r +
|
||||
3.3871328727963666080e+0) * q
|
||||
den = (((((((5.2264952788528545610e+3 * r +
|
||||
2.8729085735721942674e+4) * r +
|
||||
3.9307895800092710610e+4) * r +
|
||||
2.1213794301586595867e+4) * r +
|
||||
5.3941960214247511077e+3) * r +
|
||||
6.8718700749205790830e+2) * r +
|
||||
4.2313330701600911252e+1) * r +
|
||||
1.0)
|
||||
x = num / den
|
||||
return mu + (x * sigma)
|
||||
r = p if q <= 0.0 else 1.0 - p
|
||||
|
@ -566,105 +533,41 @@ class NormalDist:
|
|||
if r <= 5.0:
|
||||
r = r - 1.6
|
||||
# Hash sum: 49.33206_50330_16102_89036
|
||||
num = (
|
||||
(
|
||||
(
|
||||
(
|
||||
(
|
||||
(
|
||||
7.74545014278341407640e-4 * r
|
||||
+ 2.27238449892691845833e-2
|
||||
)
|
||||
* r
|
||||
+ 2.41780725177450611770e-1
|
||||
)
|
||||
* r
|
||||
+ 1.27045825245236838258e0
|
||||
)
|
||||
* r
|
||||
+ 3.64784832476320460504e0
|
||||
)
|
||||
* r
|
||||
+ 5.76949722146069140550e0
|
||||
)
|
||||
* r
|
||||
+ 4.63033784615654529590e0
|
||||
) * r + 1.42343711074968357734e0
|
||||
den = (
|
||||
(
|
||||
(
|
||||
(
|
||||
(
|
||||
(
|
||||
1.05075007164441684324e-9 * r
|
||||
+ 5.47593808499534494600e-4
|
||||
)
|
||||
* r
|
||||
+ 1.51986665636164571966e-2
|
||||
)
|
||||
* r
|
||||
+ 1.48103976427480074590e-1
|
||||
)
|
||||
* r
|
||||
+ 6.89767334985100004550e-1
|
||||
)
|
||||
* r
|
||||
+ 1.67638483018380384940e0
|
||||
)
|
||||
* r
|
||||
+ 2.05319162663775882187e0
|
||||
) * r + 1.0
|
||||
num = (((((((7.74545014278341407640e-4 * r +
|
||||
2.27238449892691845833e-2) * r +
|
||||
2.41780725177450611770e-1) * r +
|
||||
1.27045825245236838258e+0) * r +
|
||||
3.64784832476320460504e+0) * r +
|
||||
5.76949722146069140550e+0) * r +
|
||||
4.63033784615654529590e+0) * r +
|
||||
1.42343711074968357734e+0)
|
||||
den = (((((((1.05075007164441684324e-9 * r +
|
||||
5.47593808499534494600e-4) * r +
|
||||
1.51986665636164571966e-2) * r +
|
||||
1.48103976427480074590e-1) * r +
|
||||
6.89767334985100004550e-1) * r +
|
||||
1.67638483018380384940e+0) * r +
|
||||
2.05319162663775882187e+0) * r +
|
||||
1.0)
|
||||
else:
|
||||
r = r - 5.0
|
||||
# Hash sum: 47.52583_31754_92896_71629
|
||||
num = (
|
||||
(
|
||||
(
|
||||
(
|
||||
(
|
||||
(
|
||||
2.01033439929228813265e-7 * r
|
||||
+ 2.71155556874348757815e-5
|
||||
)
|
||||
* r
|
||||
+ 1.24266094738807843860e-3
|
||||
)
|
||||
* r
|
||||
+ 2.65321895265761230930e-2
|
||||
)
|
||||
* r
|
||||
+ 2.96560571828504891230e-1
|
||||
)
|
||||
* r
|
||||
+ 1.78482653991729133580e0
|
||||
)
|
||||
* r
|
||||
+ 5.46378491116411436990e0
|
||||
) * r + 6.65790464350110377720e0
|
||||
den = (
|
||||
(
|
||||
(
|
||||
(
|
||||
(
|
||||
(
|
||||
2.04426310338993978564e-15 * r
|
||||
+ 1.42151175831644588870e-7
|
||||
)
|
||||
* r
|
||||
+ 1.84631831751005468180e-5
|
||||
)
|
||||
* r
|
||||
+ 7.86869131145613259100e-4
|
||||
)
|
||||
* r
|
||||
+ 1.48753612908506148525e-2
|
||||
)
|
||||
* r
|
||||
+ 1.36929880922735805310e-1
|
||||
)
|
||||
* r
|
||||
+ 5.99832206555887937690e-1
|
||||
) * r + 1.0
|
||||
num = (((((((2.01033439929228813265e-7 * r +
|
||||
2.71155556874348757815e-5) * r +
|
||||
1.24266094738807843860e-3) * r +
|
||||
2.65321895265761230930e-2) * r +
|
||||
2.96560571828504891230e-1) * r +
|
||||
1.78482653991729133580e+0) * r +
|
||||
5.46378491116411436990e+0) * r +
|
||||
6.65790464350110377720e+0)
|
||||
den = (((((((2.04426310338993978564e-15 * r +
|
||||
1.42151175831644588870e-7) * r +
|
||||
1.84631831751005468180e-5) * r +
|
||||
7.86869131145613259100e-4) * r +
|
||||
1.48753612908506148525e-2) * r +
|
||||
1.36929880922735805310e-1) * r +
|
||||
5.99832206555887937690e-1) * r +
|
||||
1.0)
|
||||
x = num / den
|
||||
if q < 0.0:
|
||||
x = -x
|
||||
|
|
|
@ -7,7 +7,7 @@ stdout = File(_C.seq_stdout())
|
|||
stderr = File(_C.seq_stderr())
|
||||
|
||||
|
||||
def exit(status: int = 0) -> void:
|
||||
def exit(status: int = 0):
|
||||
raise SystemExit(status)
|
||||
|
||||
|
||||
|
|
|
@ -13,13 +13,13 @@ class Lock:
|
|||
raise ValueError("can't specify a timeout for a non-blocking call")
|
||||
return _C.seq_lock_acquire(self.p, block, timeout)
|
||||
|
||||
def release(self) -> void:
|
||||
def release(self):
|
||||
_C.seq_lock_release(self.p)
|
||||
|
||||
def __enter__(self) -> void:
|
||||
def __enter__(self):
|
||||
self.acquire()
|
||||
|
||||
def __exit__(self) -> void:
|
||||
def __exit__(self):
|
||||
self.release()
|
||||
|
||||
|
||||
|
@ -35,13 +35,13 @@ class RLock:
|
|||
raise ValueError("can't specify a timeout for a non-blocking call")
|
||||
return _C.seq_rlock_acquire(self.p, block, timeout)
|
||||
|
||||
def release(self) -> void:
|
||||
def release(self):
|
||||
_C.seq_rlock_release(self.p)
|
||||
|
||||
def __enter__(self) -> void:
|
||||
def __enter__(self):
|
||||
self.acquire()
|
||||
|
||||
def __exit__(self) -> void:
|
||||
def __exit__(self):
|
||||
self.release()
|
||||
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ def perf_counter_ns() -> int:
|
|||
return _C.seq_time_highres()
|
||||
|
||||
|
||||
def sleep(secs: float) -> void:
|
||||
def sleep(secs: float):
|
||||
if secs < 0:
|
||||
raise ValueError("sleep length must be non-negative")
|
||||
_C.seq_sleep(secs)
|
||||
|
@ -41,14 +41,14 @@ class TimeInterval:
|
|||
start: int
|
||||
msg: str
|
||||
|
||||
def __init__(self) -> void:
|
||||
def __init__(self):
|
||||
self.start = _C.seq_time()
|
||||
self.msg = ""
|
||||
|
||||
def __enter__(self) -> void:
|
||||
def __enter__(self):
|
||||
self.start = _C.seq_time()
|
||||
|
||||
def __exit__(self) -> void:
|
||||
def __exit__(self):
|
||||
print(self.report(self.msg), file=stderr)
|
||||
|
||||
def report(self, msg="", memory=False) -> str:
|
||||
|
@ -60,7 +60,7 @@ class TimeInterval:
|
|||
def elapsed(self) -> float:
|
||||
return float(_C.seq_time() - self.start) / 1e9
|
||||
|
||||
def tick(self, msg, memory=False) -> void:
|
||||
def tick(self, msg, memory=False):
|
||||
ret = self.report(msg)
|
||||
self.start = _C.seq_time()
|
||||
|
||||
|
@ -199,7 +199,7 @@ _MIN = 0x8000000000000000
|
|||
_MAX = 0x7FFFFFFFFFFFFFFF
|
||||
|
||||
|
||||
def _overflow() -> void:
|
||||
def _overflow():
|
||||
raise OverflowError("timestamp too large")
|
||||
|
||||
|
||||
|
|
|
@ -5,28 +5,28 @@
|
|||
|
||||
|
||||
class TestCase:
|
||||
def fail(self, standard_message: str, special_message: str = "") -> void:
|
||||
def fail(self, standard_message: str, special_message: str = ""):
|
||||
print("TEST FAILED:", special_message if special_message else standard_message)
|
||||
|
||||
def assertTrue(self, obj, msg="") -> void:
|
||||
def assertTrue(self, obj, msg=""):
|
||||
if not bool(obj):
|
||||
self.fail(f"expected object to be true: {obj}", msg)
|
||||
|
||||
def assertFalse(self, obj, msg="") -> void:
|
||||
def assertFalse(self, obj, msg=""):
|
||||
if bool(obj):
|
||||
self.fail(f"expected object to be false: {obj}", msg)
|
||||
|
||||
def assertEqual(self, first, second, msg="") -> void:
|
||||
def assertEqual(self, first, second, msg=""):
|
||||
result = first == second
|
||||
if not result:
|
||||
self.fail(f"expected equality of:\n 1: {first}\n 2: {second}", msg)
|
||||
|
||||
def assertNotEqual(self, first, second, msg="") -> void:
|
||||
def assertNotEqual(self, first, second, msg=""):
|
||||
result = first != second
|
||||
if not result:
|
||||
self.fail(f"expected inequality of:\n 1: {first}\n 2: {second}", msg)
|
||||
|
||||
def assertSequenceEqual(self, seq1, seq2, msg="") -> void:
|
||||
def assertSequenceEqual(self, seq1, seq2, msg=""):
|
||||
len1 = len(seq1)
|
||||
len2 = len(seq2)
|
||||
if len1 != len2:
|
||||
|
@ -43,27 +43,27 @@ class TestCase:
|
|||
msg,
|
||||
)
|
||||
|
||||
def assertIn(self, member, container, msg="") -> void:
|
||||
def assertIn(self, member, container, msg=""):
|
||||
if member not in container:
|
||||
self.fail(f"expected {member} to be in {container}", msg)
|
||||
|
||||
def assertNotIn(self, member, container, msg="") -> void:
|
||||
def assertNotIn(self, member, container, msg=""):
|
||||
if member in container:
|
||||
self.fail(f"expected {member} to not be in {container}", msg)
|
||||
|
||||
def assertIs(self, expr1, expr2, msg="") -> void:
|
||||
def assertIs(self, expr1, expr2, msg=""):
|
||||
if expr1 is not expr2:
|
||||
self.fail(f"expected {expr1} to be identical to {expr2}", msg)
|
||||
|
||||
def assertIsNot(self, expr1, expr2, msg="") -> void:
|
||||
def assertIsNot(self, expr1, expr2, msg=""):
|
||||
if expr1 is expr2:
|
||||
self.fail(f"expected {expr1} to not be identical to {expr2}", msg)
|
||||
|
||||
def assertIsNot(self, expr1, expr2, msg="") -> void:
|
||||
def assertIsNot(self, expr1, expr2, msg=""):
|
||||
if expr1 is expr2:
|
||||
self.fail(f"expected {expr1} to not be identical to {expr2}", msg)
|
||||
|
||||
def assertCountEqual(self, first, second, msg="") -> void:
|
||||
def assertCountEqual(self, first, second, msg=""):
|
||||
from collections import Counter
|
||||
|
||||
first_seq, second_seq = list(first), list(second)
|
||||
|
@ -74,27 +74,27 @@ class TestCase:
|
|||
if first_counter != second_counter:
|
||||
self.fail(f"expected equal counts:\n 1: {first}\n 2: {second}", msg)
|
||||
|
||||
def assertLess(self, a, b, msg="") -> void:
|
||||
def assertLess(self, a, b, msg=""):
|
||||
if not (a < b):
|
||||
self.fail(f"expected less-than:\n 1: {a}\n 2: {b}", msg)
|
||||
|
||||
def assertLessEqual(self, a, b, msg="") -> void:
|
||||
def assertLessEqual(self, a, b, msg=""):
|
||||
if not (a <= b):
|
||||
self.fail(f"expected less-than-or-equal:\n 1: {a}\n 2: {b}", msg)
|
||||
|
||||
def assertGreater(self, a, b, msg="") -> void:
|
||||
def assertGreater(self, a, b, msg=""):
|
||||
if not (a > b):
|
||||
self.fail(f"expected greater-than:\n 1: {a}\n 2: {b}", msg)
|
||||
|
||||
def assertGreaterEqual(self, a, b, msg="") -> void:
|
||||
def assertGreaterEqual(self, a, b, msg=""):
|
||||
if not (a >= b):
|
||||
self.fail(f"expected greater-than-or-equal:\n 1: {a}\n 2: {b}", msg)
|
||||
|
||||
def assertIsNone(self, obj, msg="") -> void:
|
||||
def assertIsNone(self, obj, msg=""):
|
||||
if obj is not None:
|
||||
self.fail(f"expected {obj} to be None", msg)
|
||||
|
||||
def assertIsNotNone(self, obj, msg="") -> void:
|
||||
def assertIsNotNone(self, obj, msg=""):
|
||||
if obj is None:
|
||||
self.fail(f"expected {obj} to not be None", msg)
|
||||
|
||||
|
@ -109,7 +109,7 @@ class TestCase:
|
|||
|
||||
def assertAlmostEqual(
|
||||
self, first, second, places: int = 0, msg="", delta=None
|
||||
) -> void:
|
||||
):
|
||||
if first == second:
|
||||
# shortcut
|
||||
return
|
||||
|
|
|
@ -19,8 +19,8 @@ def t2():
|
|||
t2()
|
||||
|
||||
def g[T](a: T, b: optional[T] = None):
|
||||
b_ = ~b if b else T()
|
||||
return a, b_
|
||||
b: T = b if b else T()
|
||||
return a, b
|
||||
|
||||
@test
|
||||
def t3():
|
||||
|
|
|
@ -6,7 +6,7 @@ def print_test[T](a: list[T], b: list[T]):
|
|||
return
|
||||
|
||||
if len(a) != len(b):
|
||||
print("FAILED: length of a (" + str(len(a)) + ") is not length of b (" + str(len(b)) + ")")
|
||||
print(f"FAILED: length of a ({len(a)}) is not length of b ({len(b)})")
|
||||
return
|
||||
|
||||
if len(a) == 0:
|
||||
|
@ -15,7 +15,7 @@ def print_test[T](a: list[T], b: list[T]):
|
|||
|
||||
for i in range(len(a)):
|
||||
if a[i] != b[i]:
|
||||
print("FAILED: element " + str(i) + " of a is " + str(a[i]) + " and is not equal to the element in b " + str(b[i]))
|
||||
print(f"FAILED: element {i} of a is {a[i]} and is not equal to the element in b {b[i]}")
|
||||
return
|
||||
|
||||
print("PASSED")
|
||||
|
|
|
@ -704,7 +704,7 @@ class Node[T]:
|
|||
children: List[Node[T]]
|
||||
def __init__(self, data: T):
|
||||
self.data = data
|
||||
self.children = List[Node[T]]()
|
||||
self.children = []
|
||||
print Node(2).data #: 2
|
||||
|
||||
class Node2:
|
||||
|
@ -712,7 +712,7 @@ class Node2:
|
|||
children: List[Node2]
|
||||
def __init__(self, data: int):
|
||||
self.data = data
|
||||
self.children = List[Node2]()
|
||||
self.children = []
|
||||
print Node2(3).data #: 3
|
||||
|
||||
#%% class_auto_init,barebones
|
||||
|
|
|
@ -636,7 +636,7 @@ print a.__class__ #: Array[int]
|
|||
|
||||
#%% typeof,barebones
|
||||
a = 5
|
||||
z = List[type(a)]()
|
||||
z = []
|
||||
z.append(6)
|
||||
print z.__class__, z, type(1.1).__class__ #: List[int] [6] float
|
||||
|
||||
|
|
|
@ -306,8 +306,8 @@ test_infinity_and_nan_constants()
|
|||
@test
|
||||
def test_user_object():
|
||||
class MyComplexOS:
|
||||
T: type
|
||||
value: T
|
||||
T: type
|
||||
|
||||
def __init__(self, value: T):
|
||||
self.value = value
|
||||
|
|
|
@ -22,7 +22,7 @@ def test_heapify():
|
|||
@test
|
||||
def test_naive_nbest():
|
||||
data = [randrange(2000) for i in range(1000)]
|
||||
heap = List[int]()
|
||||
heap = []
|
||||
for item in data:
|
||||
heapq.heappush(heap, item)
|
||||
if len(heap) > 10:
|
||||
|
@ -99,7 +99,7 @@ def test_heapsort():
|
|||
heap = data[:]
|
||||
heapq.heapify(heap)
|
||||
else: # The rest of the time, use heappush
|
||||
heap = List[int]()
|
||||
heap = []
|
||||
for item in data:
|
||||
heapq.heappush(heap, item)
|
||||
heap_sorted = [heapq.heappop(heap) for i in range(size)]
|
||||
|
@ -206,6 +206,13 @@ def test_comparison_operator():
|
|||
assert hsort(data, LT) == target
|
||||
|
||||
|
||||
@test
|
||||
def test_merge():
|
||||
# assert [0, 1, 2, 3, 4, 5, 5, 7, 8, 10, 15, 20, 25] == list(heapq.merge([1,3,5,7], [0,2,4,8], [5,10,15,20], [], [25]))
|
||||
# assert ['dog', 'cat', 'fish', 'horse', 'kangaroo'] == list(heapq.merge(['dog', 'horse'], ['cat', 'fish', 'kangaroo'], key=len))
|
||||
pass
|
||||
|
||||
|
||||
test_heapify()
|
||||
test_naive_nbest()
|
||||
test_nsmallest()
|
||||
|
@ -216,3 +223,4 @@ test_heappushpop()
|
|||
test_heappop_max()
|
||||
test_heapsort()
|
||||
# test_comparison_operator()
|
||||
# test_merge()
|
||||
|
|
|
@ -186,41 +186,8 @@ def test_quantiles():
|
|||
(6, [150.0, 200.0, 300.0, 400.0, 600.0]),
|
||||
(8, [137.5, 175.0, 225.0, 300.0, 375.0, 500.0, 650.0]),
|
||||
(10, [130.0, 160.0, 190.0, 240.0, 300.0, 360.0, 440.0, 560.0, 680.0]),
|
||||
(
|
||||
12,
|
||||
[
|
||||
125.0,
|
||||
150.0,
|
||||
175.0,
|
||||
200.0,
|
||||
250.0,
|
||||
300.0,
|
||||
350.0,
|
||||
400.0,
|
||||
500.0,
|
||||
600.0,
|
||||
700.0,
|
||||
],
|
||||
),
|
||||
(
|
||||
15,
|
||||
[
|
||||
120.0,
|
||||
140.0,
|
||||
160.0,
|
||||
180.0,
|
||||
200.0,
|
||||
240.0,
|
||||
280.0,
|
||||
320.0,
|
||||
360.0,
|
||||
400.0,
|
||||
480.0,
|
||||
560.0,
|
||||
640.0,
|
||||
720.0,
|
||||
],
|
||||
),
|
||||
(12, [125.0, 150.0, 175.0, 200.0, 250.0, 300.0, 350.0, 400.0, 500.0, 600.0, 700.0]),
|
||||
(15, [120.0, 140.0, 160.0, 180.0, 200.0, 240.0, 280.0, 320.0, 360.0, 400.0, 480.0, 560.0, 640.0, 720.0])
|
||||
]:
|
||||
assert statistics.quantiles(data, n=n, method="inclusive") == expected
|
||||
|
||||
|
|
|
@ -761,6 +761,26 @@ def test_repr():
|
|||
assert repr("\"'") == "'\"\\''"
|
||||
|
||||
|
||||
@test
|
||||
def test_algorithms():
|
||||
from algorithms.strings import *
|
||||
|
||||
assert [1, 2] == list(string_search_slow('abbba', 'bb'))
|
||||
assert [2, 1] == list(rstring_search_slow('abbbc', 'bb'))
|
||||
|
||||
assert [0, 9, 11, 14] == list(string_search_slow('1214313141212 12', '12'))
|
||||
assert [0, 9, 11, 14] == list(string_search_rabin_karp('1214313141212 12', '12', 1001))
|
||||
assert [0, 9, 11, 14] == list(string_search_kmp('1214313141212 12', '12'))
|
||||
|
||||
assert [0, 9, 12] == list(string_search_slow('AABAACAADAABAABA', 'AABA'))
|
||||
assert [0, 9, 12] == list(string_search_rabin_karp('AABAACAADAABAABA', 'AABA', 1001))
|
||||
assert [0, 9, 12] == list(string_search_kmp('AABAACAADAABAABA', 'AABA'))
|
||||
|
||||
assert [10] == list(string_search_slow('ABABDABACDABABCABAB', 'ABABCABAB'))
|
||||
assert [10] == list(string_search_rabin_karp('ABABDABACDABABCABAB', 'ABABCABAB', 101))
|
||||
assert [10] == list(string_search_kmp('ABABDABACDABABCABAB', 'ABABCABAB'))
|
||||
|
||||
|
||||
test_isdigit()
|
||||
test_islower()
|
||||
test_isupper()
|
||||
|
@ -806,3 +826,4 @@ test_fstr()
|
|||
test_slice()
|
||||
test_join()
|
||||
test_repr()
|
||||
test_algorithms()
|
||||
|
|
Loading…
Reference in New Issue