Skip to content

Instantly share code, notes, and snippets.

@yuri-potatoq
Last active March 24, 2026 14:17
Show Gist options
  • Select an option

  • Save yuri-potatoq/250ef624ca810a776328d1068c81b967 to your computer and use it in GitHub Desktop.

Select an option

Save yuri-potatoq/250ef624ca810a776328d1068c81b967 to your computer and use it in GitHub Desktop.
Weird cliboard using Stack ADT
class Clipboard:
ALLOWED_COMMANDS = [
# delete/pop the last inserted content
'd',
# copy/push an content to clipboard
'c',
# paste/pop the last inserted content
'p',
# finish the repl
'q',
# show/print the stack representation
's',
]
def __init__(self, stack: Stack):
self.stack = stack
def copy_text(self, text):
self.stack.push(text)
def paste_and_consume(self) -> str | None:
return self.stack.pop()
def paste_text(self) -> str | None:
return self.stack.get()
def parse_line(self, line: str) -> tuple[str, str | None] | ValueError:
command, content = "", None
for idx, lt in enumerate(line):
if idx == 0:
if not lt in self.ALLOWED_COMMANDS:
return ValueError(f"Commando [{lt}] não implementado: [{self.ALLOWED_COMMANDS}].")
command = lt
continue
else:
if lt == " ":
continue
else:
content = line[idx:]
break
return (command, content)
def run(self):
while True:
match self.parse_line(input("> ")):
case ('c', content):
if not content:
print("comando de [copy] precisa de conteúdo para ser copiado.")
continue
self.copy_text(content)
case ('d', None):
if not self.paste_and_consume():
print("Clipboard já está vazio.")
case ('p', None):
text = self.paste_text()
if not text:
print("Sem items no clipboard")
else:
print(text)
case ('q', None):
print("")
return
case ('s', None):
print(f"Stack:\n{self.stack}")
case ValueError() as err:
print(err)
from dataclasses import dataclass
from enum import Enum
class TokenKind(Enum):
WORD = 1
SPACE = 2
@dataclass
class TextEditorToken:
content: str
kind: TokenKind
class TextEditor:
def __init__(self, stack: Stack):
self.stack = stack
def write(self, line):
for it in self.parse_line(line):
self.stack.push(it)
def undo(self):
self.stack.pop()
def parse_line(self, line) -> list[TextEditorToken]:
items = []
cursor = 0
line_sz = len(line)
def peek_next() -> str | None:
if cursor+1 > line_sz-1:
return None
return line[cursor+1]
def collect_word(is_space: bool) -> str:
nonlocal cursor
word = ""
while True:
tk = peek_next()
if not tk:
return word
if is_space:
if tk == " ":
word += tk
cursor += 1
else:
return word
else:
if tk != " ":
word += tk
cursor += 1
else:
return word
while cursor < line_sz:
char = line[cursor]
print(f"char [{char}]")
print(f"cursor [{cursor}]")
if char == " ":
space = char + collect_word(True)
items.append(TextEditorToken(space, TokenKind.SPACE))
else:
word = char + collect_word(False)
items.append(TextEditorToken(word, TokenKind.WORD))
cursor += 1
return items
# TODO: make it generic over type T
class Stack:
def __init__(self):
self.items = list()
self.size = 0
def push(self, item):
# ok, you can use append, but only this one '-'
self.items.append(item)
self.size += 1
def pop(self):
if self.size < 1:
return None
# don't use .pop(), use your brain instead!
it = self.items[self.size-1]
self.items = self.items[:self.size-1]
self.size -= 1
return it
def get(self):
if self.size < 1:
return None
# don't use get(-1) or arr[-1], use your brain instead
return self.items[self.size-1]
def __str__(self) -> str:
stack_str = ""
# don't use reverse, use your brain instead!
counter = len(self.items)-1
while counter >= 0:
stack_str += f"{self.items[counter]} -> [{counter}]\n"
counter -= 1
return stack_str
def main():
try:
te = TextEditor(Stack())
te.write("Olá mundo eu gosto de você")
te.undo()
te.undo()
te.undo()
te.undo()
te.undo()
te.undo()
te.undo()
te.write("isso é um test")
except KeyboardInterrupt:
print("")
except Exception as err:
print(f"Erro desconhecido: {err.args}")
# entrypoint guard
if __name__ == '__main__':
main()cat: s: No such file or directory
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment