This repository was archived by the owner on Apr 4, 2024. It is now read-only.
forked from diffplug/selfie
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSlice.py
84 lines (68 loc) · 3.06 KB
/
Slice.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
from typing import Optional
from typing import Union
from collections import Counter
class Slice:
"""Represents a slice of a base string from startIndex to endIndex."""
def __init__(self, base: str, startIndex: int = 0, endIndex: Optional[int] = None) -> None:
self.base = base
self.base = base
self.startIndex = startIndex
self.endIndex = endIndex if endIndex is not None else len(base)
assert 0 <= self.startIndex <= self.endIndex <= len(base), "Invalid start or end index"
def __len__(self) -> int:
return self.endIndex - self.startIndex
def __getitem__(self, index: int) -> str:
if not (0 <= index < len(self)):
raise IndexError("Index out of range")
return self.base[self.startIndex + index]
def subSequence(self, start: int, end: int) -> 'Slice':
return Slice(self.base, self.startIndex + start, self.startIndex + end)
def trim(self) -> 'Slice':
start, end = 0, len(self)
while start < end and self[start].isspace():
start += 1
while start < end and self[end - 1].isspace():
end -= 1
return self.subSequence(start, end) if start > 0 or end < len(self) else self
def __str__(self) -> str:
return self.base[self.startIndex:self.endIndex]
def sameAs(self, other: Union['Slice', str]) -> bool:
if isinstance(other, Slice):
return str(self) == str(other)
elif isinstance(other, str):
if len(self) != len(other):
return False
for i in range(len(self)):
if self[i] != other[i]:
return False
return True
return False
def indexOf(self, lookingFor: str, startOffset: int = 0) -> int:
result = self.base.find(lookingFor, self.startIndex + startOffset, self.endIndex)
return -1 if result == -1 else result - self.startIndex
def unixLine(self, count: int) -> 'Slice':
assert count > 0, "Count must be positive"
lineStart = 0
for i in range(1, count):
lineStart = self.indexOf('\n', lineStart)
assert lineStart >= 0, f"This string has only {i - 1} lines, not {count}"
lineStart += 1
lineEnd = self.indexOf('\n', lineStart)
return Slice(self.base, self.startIndex + lineStart, self.endIndex if lineEnd == -1 else self.startIndex + lineEnd)
def __eq__(self, other: object) -> bool:
if self is other:
return True
if isinstance(other, Slice):
return self.sameAs(other)
return False
def __hash__(self) -> int:
h = 0
for i in range(len(self)):
h = 31 * h + ord(self[i])
return h
def replaceSelfWith(self, s: str) -> str:
return self.base[:self.startIndex] + s + self.base[self.endIndex:]
def count(self, char: str) -> int:
return Counter(self.base[self.startIndex:self.endIndex])[char]
def baseLineAtOffset(self, index: int) -> int:
return 1 + Slice(self.base, 0, index).count('\n')