Last active
March 24, 2026 14:17
-
-
Save yuri-potatoq/250ef624ca810a776328d1068c81b967 to your computer and use it in GitHub Desktop.
Weird cliboard using Stack ADT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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