Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

Commit

Permalink
Port Slice (#15 closes #6)
Browse files Browse the repository at this point in the history
  • Loading branch information
nedtwigg authored Feb 27, 2024
2 parents 12638a2 + 1cc0a97 commit d4bac8b
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 0 deletions.
84 changes: 84 additions & 0 deletions python/selfie-lib/selfie_lib/Slice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,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')
1 change: 1 addition & 0 deletions python/selfie-lib/selfie_lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
from .selina import get_interesting_fact as get_interesting_fact
from .harvir import silly_addition as silly_addition
from .edwin import simple_subtraction as simple_subtraction
from .Slice import Slice as Slice
13 changes: 13 additions & 0 deletions python/selfie-lib/tests/Slice_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from selfie_lib import Slice

def test_unixLine():
slice_1 = Slice("A single line")
assert str(slice_1.unixLine(1)) == "A single line"

one_two_three = Slice("\nI am the first\nI, the second\n\nFOURTH\n")
assert str(one_two_three.unixLine(1)) == ""
assert str(one_two_three.unixLine(2)) == "I am the first"
assert str(one_two_three.unixLine(3)) == "I, the second"
assert str(one_two_three.unixLine(4)) == ""
assert str(one_two_three.unixLine(5)) == "FOURTH"
assert str(one_two_three.unixLine(6)) == ""

0 comments on commit d4bac8b

Please sign in to comment.