Bolhaverso

Reader

pt-br

Leia os posts do bolha.blog.

en-us

Read all posts from our users.

from Riverfount

Resumo:
O Princípio da Inversão de Dependência (DIP), parte do conjunto SOLID, é fundamental para criar sistemas sustentáveis, extensíveis e fáceis de testar. Este artigo explora como aplicá-lo em Python usando typing.Protocol e injeção de dependência, com foco em arquiteturas limpas e aplicação prática em sistemas corporativos.

Contexto

Projetos orientados a objetos de longo prazo exigem mais do que modularidade: precisam de estabilidade arquitetural. O Princípio da Inversão de Dependência (Dependency Inversion Principle – DIP) aborda exatamente esse ponto.
Ele recomenda que módulos de alto nível (os que contêm as regras de negócio) não conheçam os detalhes de baixo nível (implementações, drivers, frameworks), mas interajam por meio de abstrações.

Mesmo em uma linguagem dinâmica como Python, onde acoplamentos podem parecer menos problemáticos, o DIP se torna essencial em sistemas corporativos com múltiplos serviços e integrações externas, garantindo desacoplamento e testabilidade.

O problema: quando o código depende de detalhes

Imagine um serviço que envia notificações a usuários. Uma implementação comum é instanciar dependências diretamente dentro da classe de negócio:

class EmailService:
    def send_email(self, to: str, message: str) -> None:
        print(f"Enviando e-mail para {to}: {message}")


class UserNotifier:
    def __init__(self) -> None:
        self.email_service = EmailService()  # dependência concreta

    def notify_user(self, user_email: str, msg: str) -> None:
        self.email_service.send_email(user_email, msg)

Embora funcional, essa abordagem cria acoplamento rígido. Qualquer mudança no método de envio (ex.: SMS, Push, Webhook) exige alterar UserNotifier, o que viola diretamente o DIP e propaga dependências desnecessárias.

A solução: abstrações com Protocols

O DIP recomenda inverter essa dependência — o módulo de alto nível deve depender de uma abstração, e não de um detalhe concreto.
Desde o Python 3.8, a PEP 544 introduziu typing.Protocol, permitindo descrever contratos de interface de modo estático e seguro.

from typing import Protocol


class Notifier(Protocol):
    def send(self, to: str, message: str) -> None:
        ...

A partir do contrato, diferentes mecanismos podem ser implementados:

class EmailNotifier:
    def send(self, to: str, message: str) -> None:
        print(f"Email para {to}: {message}")


class SMSNotifier:
    def send(self, to: str, message: str) -> None:
        print(f"SMS enviado para {to}: {message}")

Assim, o módulo de negócio depende apenas de uma abstração genérica:

class UserNotifier:
    def __init__(self, notifier: Notifier) -> None:
        self._notifier = notifier

    def notify(self, user_email: str, msg: str) -> None:
        self._notifier.send(user_email, msg)

O uso torna-se desacoplado e configurável:

email_notifier = EmailNotifier()
user_notifier = UserNotifier(email_notifier)
user_notifier.notify("joao@example.com", "Bem-vindo ao sistema!")

sms_notifier = SMSNotifier()
user_notifier = UserNotifier(sms_notifier)
user_notifier.notify("+5511999999999", "Código de autenticação: 123456")

Benefícios e impacto arquitetural

A aplicação do DIP resulta em ganhos tangíveis de engenharia:

  • Desacoplamento estrutural: classes de domínio não conhecem implementações concretas.
  • Extensibilidade controlada: adicionar novos canais ou comportamentos não requer refatoração de código existente.
  • Testabilidade facilitada: dependências podem ser simuladas ou injetadas em testes unitários.
  • Conformidade com arquiteturas limpas: o domínio permanece independente da infraestrutura.

Em projetos complexos, contêineres de injeção como dependency-injector ou punq podem automatizar a resolução de dependências sem comprometer a clareza arquitetural.

Boas práticas e armadilhas comuns

Boas práticas

  • Defina contratos explícitos: sempre que um módulo precisar interagir com outro de baixo nível, defina um Protocol.
  • Mantenha o domínio puro: o código de negócio deve ser independente de frameworks e bibliotecas externas.
  • Use tipagem estática: ferramentas como mypy ajudam a validar conformidade de implementações com Protocols.
  • Aplique injeção de dependência: crie instâncias fora do domínio e injete-as no construtor (ou em fábricas específicas).

Armadilhas frequentes

  • Overengineering: evite criar abstrações desnecessárias. Se há apenas uma implementação e não há expectativa de variação, o custo de manter o contrato pode não compensar.
  • Dependência indireta: trocar dependência direta por uma indireta mal desenhada (por exemplo, uma abstração genérica demais) reduz a clareza do sistema.
  • Confusão entre abstração e herança: Protocols substituem interfaces, não exigem herança e não impõem rigidez hierárquica.

Adotar o DIP não significa adicionar camadas de complexidade artificial, mas desenhar fronteiras claras entre políticas e detalhes técnicos.

Conclusão

O Princípio da Inversão de Dependência é mais do que uma regra teórica do SOLID: é uma mentalidade de design voltada à estabilidade e evolução contínua.
Em Python, o uso de Protocol e injeção de dependência permite aplicar o DIP de forma idiomática, preservando a simplicidade da linguagem sem abrir mão da qualidade arquitetural.
Em sistemas que precisam evoluir com segurança, o DIP é uma das práticas mais valiosas — e um dos marcos de maturidade de um engenheiro de software sênior.

 
Read more...

from Riverfount

O Princípio da Segregação de Interfaces (ISP — Interface Segregation Principle) é um dos pilares do SOLID e trata diretamente da qualidade dos contratos entre componentes. Em essência, ele afirma que uma classe não deve ser obrigada a depender de métodos que não utiliza. Essa regra incentiva o desenho de interfaces menores, mais coesas e representativas de um papel específico no sistema.

Na prática, o ISP força uma reflexão arquitetural: qual é a verdadeira responsabilidade dessa abstração? Se a resposta envolve comportamentos heterogêneos, a interface provavelmente está concentrando demasiadas responsabilidades — um sinal de design frágil e baixo reuso.

O problema das interfaces genéricas

Considere um caso comum: um módulo que define uma interface genérica de “dispositivo multifuncional”. Ela impõe à hierarquia de classes um contrato extenso, mesmo que nem todas as implementações precisem de todas as operações.

from abc import ABC, abstractmethod

class MultiFunctionDevice(ABC):
    @abstractmethod
    def print_document(self, document): pass

    @abstractmethod
    def scan_document(self, document): pass

    @abstractmethod
    def fax_document(self, document): pass


class BasicPrinter(MultiFunctionDevice):
    def print_document(self, document):
        print(f"Imprimindo: {document}")

    def scan_document(self, document):
        raise NotImplementedError("Este dispositivo não suporta digitalização")

    def fax_document(self, document):
        raise NotImplementedError("Este dispositivo não envia fax")

Aqui, BasicPrinter viola o ISP porque é forçada a implementar métodos irrelevantes. Qualquer alteração em MultiFunctionDevice pode afetar classes que não deveriam ter relação entre si.

Refinando o design com interfaces específicas

Para evitar esse problema, segmentamos as interfaces em abstrações menores e mais focadas:

from abc import ABC, abstractmethod

class Printable(ABC):
    @abstractmethod
    def print_document(self, document): pass

class Scannable(ABC):
    @abstractmethod
    def scan_document(self, document): pass

class Faxable(ABC):
    @abstractmethod
    def fax_document(self, document): pass


class BasicPrinter(Printable):
    def print_document(self, document):
        print(f"Imprimindo: {document}")


class MultiFunctionPrinter(Printable, Scannable, Faxable):
    def print_document(self, document):
        print(f"Imprimindo: {document}")

    def scan_document(self, document):
        print(f"Digitalizando: {document}")

    def fax_document(self, document):
        print(f"Enviando fax: {document}")

Cada interface é coesa e independente. As classes agora implementam apenas as operações relevantes às suas funcionalidades, reduzindo o acoplamento e melhorando a clareza estrutural.

Abordagem moderna com typing.Protocol

A partir do Python 3.8, typing.Protocol permite expressar contratos comportamentais baseados em tipagem estrutural (também chamada de duck typing verificado estaticamente). Esse recurso é especialmente compatível com o ISP, pois elimina a necessidade de herança explícita para validar conformidade de tipo.

from typing import Protocol

class Printable(Protocol):
    def print_document(self, document: str) -> None: ...

class Scannable(Protocol):
    def scan_document(self, document: str) -> None: ...


class BasicPrinter:
    def print_document(self, document: str) -> None:
        print(f"Imprimindo: {document}")


class SmartDevice:
    def print_document(self, document: str) -> None:
        print(f"Imprimindo: {document}")

    def scan_document(self, document: str) -> None:
        print(f"Digitalizando: {document}")


def print_any(printer: Printable, content: str) -> None:
    printer.print_document(content)

Observe que BasicPrinter e SmartDevice não herdam explicitamente de Printable ou Scannable, mas o type checker reconhecerá ambas as classes como compatíveis por possuírem os métodos exigidos. Essa abordagem é vantajosa porque:

  • Mantém baixo acoplamento entre tipos, reforçando a aplicação do ISP.
  • Usa duck typing com suporte de tipagem estática (útil em ferramentas como mypy).
  • Favorece design evolutivo; novos comportamentos podem ser adicionados a outras classes sem quebrar a hierarquia.

Assim, Protocol é a forma moderna e idiomática de aplicar o ISP em projetos Python, tornando clara a separação de responsabilidades e preservando a flexibilidade da linguagem.

Conclusão

O ISP é mais que um princípio de design: é uma diretriz para compor sistemas orientados a abstrações coesas e independentes. No ecossistema Python, a evolução da tipagem com abc e Protocol oferece duas formas complementares de expressar esse princípio — uma baseada em herança nominal, outra em compatibilidade estrutural.

Projetar interfaces enxutas e especializadas é um ato de disciplina arquitetural: reduz o impacto de mudanças, aumenta a clareza e favorece a manutenibilidade a longo prazo. Em times maduros, a aplicação do ISP reflete um domínio avançado de separação de responsabilidades e uma compreensão profunda da dinâmica entre contrato e implementação.

 
Read more...

from Riverfount

No mundo da programação orientada a objetos, o Princípio de Substituição de Liskov (LSP) é um guia essencial para criar sistemas robustos e flexíveis. Porém, em Python, esse princípio ganha uma nuance especial graças ao duck typing e aos protocolos, que mudam completamente a forma como pensamos em substituição e hierarquia.

Neste post, vamos explorar como esses conceitos se entrelaçam, por que o LSP faz tanto sentido na linguagem pythonica e como seu entendimento ajuda a escrever códigos mais limpos, seguros e reutilizáveis — tudo isso sem depender exclusivamente de herança formal. Prepare-se para olhar para o LSP através das lentes de Python e descobrir ferramentas poderosas para o design de software elegante e eficiente.

LSP e Duck Typing: O Poder do Comportamento

Em linguagens estaticamente tipadas, o LSP está intimamente ligado à hierarquia de classes e à herança formal. Já em Python, graças ao duck typing, não é a herança que define a possibilidade de substituição, mas o comportamento do objeto. Se um objeto “grasna” e “anda” como um pato, ele pode ser tratado como um pato, independentemente de sua árvore de classes.

Exemplo simples:

class PatoReal:
    def voar(self):
        print("Voando!")

    def grasnar(self):
        print("Quack!")

class PatoDeBorracha:
    def voar(self):
        raise NotImplementedError("Não posso voar")

    def grasnar(self):
        print("Squeak!")

def fazer_o_pato_grasnar(pato):
    pato.grasnar()

pato_real = PatoReal()
pato_borracha = PatoDeBorracha()

fazer_o_pato_grasnar(pato_real)   # Quack!
fazer_o_pato_grasnar(pato_borracha)  # Squeak!

Aqui, ambos os objetos possuem o método grasnar(), então o código funciona para ambos. No entanto, o método voar() do PatoDeBorracha quebra a expectativa do comportamento esperado, violando o LSP caso o código cliente dependa dele.

Protocolos e o Contrato Explícito

Os protocolos (introduzidos com PEP 544) formalizam essa ideia apresentando um tipo estrutural onde uma “interface” é definida pelo conjunto de métodos que um objeto deve implementar para ser considerado um subtipo daquele protocolo. Diferente da herança tradicional, o protocolo não exige que a classe declare que o implementa explicitamente; ele verifica a compatibilidade estrutural.

Exemplo com protocolo:

from typing import Protocol

class Pato(Protocol):
    def voar(self) -> None:
        ...
    def grasnar(self) -> None:
        ...

class PatoReal:
    def voar(self) -> None:
        print("Voando!")

    def grasnar(self) -> None:
        print("Quack!")

class PatoDeBorracha:
    def voar(self) -> None:
        raise NotImplementedError("Não posso voar")

    def grasnar(self) -> None:
        print("Squeak!")

def fazer_o_pato_voar(pato: Pato) -> None:
    pato.voar()

fazer_o_pato_voar(PatoReal())    # Voando!
fazer_o_pato_voar(PatoDeBorracha())  # Erro: viola LSP

O protocolo Pato define claramente o contrato esperado. Substituir um PatoReal por PatoDeBorracha falha porque PatoDeBorracha não mantém a garantia do método voar.

Interseção do LSP com Duck Typing e Protocolos

  • O LSP reforça que substitutos devem manter o contrato de comportamento original.
  • Duck typing foca na existência desse comportamento ao invés da herança.
  • Protocolos formalizam esse contrato, tornando explícita a interface esperada.
  • Em Python, usar protocolos deixa mais claro onde o LSP pode ser inadvertidamente violado, especialmente em projetos maiores.

Benefícios Práticos

  • Evita exceções inesperadas ou falhas ao substituir objetos que não mantêm o contrato.
  • Permite maior flexibilidade, pois não é necessária herança pura para garantir substituibilidade.
  • Facilita a manutenção e extensibilidade com tipos mais expressivos e contratos claros.
  • Compatibiliza com a filosofia pythonica de código explícito, porém flexível.

Dessa forma, o LSP em Python é mais um guia para respeitar o comportamento esperado, alinhado naturalmente com a dinâmica do duck typing e o rigor dos protocolos, garantindo que seu código seja ao mesmo tempo flexível, seguro e fácil de estender.

 
Read more...

from Riverfount

O Princípio Aberto-Fechado (Open-Closed Principle), um dos pilares do SOLID, é essencial para quem busca escrever código Python orientado a objetos mais flexível, escalável e de fácil manutenção. Ele estabelece que entidades de software — como classes, módulos e funções — devem estar abertas para extensão, mas fechadas para modificação.
Em outras palavras, o comportamento do sistema deve poder evoluir sem necessidade de alterar o código existente.

Entendendo o Princípio Aberto-Fechado

  • Aberto para extensão significa que o sistema pode adquirir novas funcionalidades.
  • Fechado para modificação significa que essas melhorias não devem exigir alterações nas implementações originais, reduzindo a chance de regressões e preservando a integridade do código já testado.

Em Python, a aplicação desse princípio está fortemente relacionada ao uso de abstrações, polimorfismo e injeção de dependências. Projetar para interfaces (ou classes abstratas) é o caminho para permitir evolução sem quebrar funcionalidades existentes.

Exemplo Clássico: Onde o OCP é Quebrado

class Calc:
    def operacao(self, tipo, a, b):
        if tipo == "soma":
            return a + b
        elif tipo == "subtracao":
            return a - b
        # E assim por diante...

Esse design é comum, mas viola o princípio: sempre que surgir uma nova operação, o método operacao precisará ser alterado. Quanto mais lógica for adicionada, mais frágil e mais difícil de testar o código se tornará.

Aplicando o OCP com Polimorfismo

Podemos refatorar usando uma hierarquia de classes, permitindo adicionar novas operações sem modificar código existente:

from abc import ABC, abstractmethod

class Operacao(ABC):
    @abstractmethod
    def calcular(self, a, b):
        pass

class Soma(Operacao):
    def calcular(self, a, b):
        return a + b

class Subtracao(Operacao):
    def calcular(self, a, b):
        return a - b


def executar_operacao(operacao: Operacao, a, b):
    return operacao.calcular(a, b)


# Uso:
resultado = executar_operacao(Soma(), 2, 3)

Agora, para adicionar uma nova operação — por exemplo, uma multiplicação — basta criar uma nova subclasse:

class Multiplicacao(Operacao):
    def calcular(self, a, b):
        return a * b

Nenhuma modificação no código principal é necessária. Isso torna o design mais estável, previsível e fácil de evoluir.

Onde o OCP Brilha na Prática

  • Regras de negócio variáveis: Cálculo de comissões, descontos ou impostos que variam conforme o tipo de cliente ou o contrato.
  • Estratégias de notificação: Diferentes canais (email, SMS, push, WhatsApp) com uma interface comum.
  • Sistemas de plugins: Ferramentas extensíveis em que cada plugin adiciona comportamento por meio de subclasses.

Aliás, o padrão Strategy é uma aplicação direta do OCP, permitindo selecionar comportamentos em tempo de execução sem alterar código central.

Por Que Adotar o OCP

  • Facilita a evolução do sistema sem comprometer código validado.
  • Reduz o acoplamento e incentiva abstrações limpas.
  • Melhora a testabilidade, pois cada comportamento é isolado em sua própria classe.
  • Promove um design mais profissional, típico de projetos Python maduros.

Projetar com o Princípio Aberto-Fechado é dar um passo estratégico rumo a um código mais sustentável, que cresce com o produto — e não contra ele.

 
Read more...

from Riverfount

Em Python, é comum — especialmente pela flexibilidade da linguagem e pelo foco em produtividade — cairmos na armadilha de escrever grandes blocos de código em uma única função, método ou rota. Às vezes, é tentador resolver “tudo em um só lugar”: validar os dados, consultar o banco, tratar erros e ainda montar a resposta final.

Mas essa abordagem tem um preço. O código cresce, as responsabilidades se misturam e, de repente, você tem uma função que faz de tudo — e nada bem feito.

O que diz o Princípio da Responsabilidade Única (SRP)

Diretamente inspirado no primeiro princípio do SOLID, o SRP (“Single Responsibility Principle”) afirma que cada função, classe ou módulo deve ter apenas um motivo para mudar. Em outras palavras, cada unidade de código deve ter uma responsabilidade bem definida.

Isso melhora a legibilidade, reduz o acoplamento e torna o sistema muito mais fácil de evoluir.

Vamos ver um exemplo prático.

Exemplo: o anti-padrão

@app.route("/users", methods=["POST"])
def create_user():
    # 1. Validação
    data = request.json
    if "email" not in data:
        return {"error": "Email is required"}, 400

    # 2. Inserção no banco
    conn = sqlite3.connect("db.sqlite")
    cursor = conn.cursor()
    cursor.execute("INSERT INTO users (email) VALUES (?)", (data["email"],))
    conn.commit()
    conn.close()

    # 3. Notificação (simulada)
    send_welcome_email(data["email"])

    return {"message": "User created successfully"}, 201

Essa rota funciona, mas concentra três responsabilidades distintas: validação de dados, acesso ao banco e envio de e-mail. Isso viola o SRP.

Aplicando o princípio

Vamos refatorar o código, dividindo as responsabilidades:

def validate_user_data(data):
    if "email" not in data:
        raise ValueError("Email is required")

def save_user_to_db(email):
    conn = sqlite3.connect("db.sqlite")
    with conn:
        conn.execute("INSERT INTO users (email) VALUES (?)", (email,))
    return True

def send_notification(email):
    send_welcome_email(email)

@app.route("/users", methods=["POST"])
def create_user():
    try:
        data = request.json
        validate_user_data(data)
        save_user_to_db(data["email"])
        send_notification(data["email"])
        return {"message": "User created successfully"}, 201
    except ValueError as e:
        return {"error": str(e)}, 400

Agora a rota faz apenas o que deve: coordena o fluxo entre funções auxiliares. Cada função tem uma única responsabilidade clara e testável.

Por que isso é importante

  • Manutenibilidade: funções pequenas e claras são mais fáceis de entender e de modificar.
  • Testabilidade: testar cada parte isoladamente torna-se trivial, facilitando os testes unitários.
  • Reutilização: funções com responsabilidades únicas podem ser reaproveitadas em outros contextos.
  • Escalabilidade: um código modular cresce de forma mais previsível e segura.
  • Menor acoplamento: reduz a dependência entre componentes e torna o sistema mais flexível.
  • Mocks e stubs: com responsabilidades bem separadas, é mais fácil simular dependências em testes.
  • Depuração: localizar bugs é muito mais simples quando cada função faz apenas uma coisa.

Conclusão

Ao olhar para uma função, faça a si mesmo esta pergunta: “Quantas coisas ela faz?”. Se a resposta for mais de uma, é hora de quebrar o código em partes menores. O princípio da responsabilidade única não é apenas teórico — é uma forma prática de escrever código mais limpo, testável e confiável em Python.

 
Read more...

from Paulo Henrique Rodrigues Pinheiro

Clara Charf

Morreu ontem, 3 de novembro de 2025, aos 100 anos, a camarada Clara Charf, militante revolucionária forjada nas lutas comunistas desde a juventude. Nascida em 17 de julho de 1925, Clara ingressou no Partido Comunista Brasileiro (PCB) ainda adolescente, tornando-se uma das vozes ativas na resistência à ditadura do Estado Novo.

Casada com Carlos Marighella, com quem compartilhou não apenas a vida afetiva, mas também o profundo compromisso com a transformação social, Clara teve uma longa carreira na estrutura partidária do velho PCB. Utilizando suas prerrogativas profissionais como aeromoça da Panair do Brasil, desempenhou papel crucial na logística da militância, transportando documentos clandestinos do Partidão por diversas cidades, cruzando fronteiras e arriscando a própria liberdade em nome da organização revolucionária.

Além dessa atuação discreta porém fundamental, Clara participou ativamente de inúmeras outras tarefas revolucionárias – desde a organização de bases operárias até a coordenação de ações de solidariedade internacionalista. Após o golpe de 1964, aprofundou seu engajamento na resistência à ditadura militar, tornando-se uma das fundadoras da Ação Libertadora Nacional (ALN), organização da qual Marighella seria principal dirigente.

Sua trajetória não se limitou à militância armada. Com a redemocratização, Clara Charf seguiu na linha de frente das lutas sociais, dedicando-se especialmente à causa feminista e tornando-se uma das principais referências do movimento de mulheres no Brasil. Foi fundadora da União de Mulheres de São Paulo e esteve envolvida nas campanhas pela Anistia ampla, geral e irrestrita e na construção do Partido dos Trabalhadores.

 
Leia mais...

from Fure a bolha

#tecnologia #tecnootimismo #IA

Introdução

Há uma ideia muito errada de que inteligência artificial seria juiz confiável e imparcial. Tem relato na rede social Lemmy de um infeliz cuja namorada vive jogando as brigas no casal no ChatGPT para dizer que o cara estava errado mesmo, o ChatGPT confirmou.

Na minha área (TI), antigamente era bem mais comum as pessoas lerem manuais info; man pages; e livros sobre algoritmos, matemática, engenharia de software. Aí quando se popularizaram sítios como Stack Overflow, alguns desenvolvedores passaram a copiar trechos prontos desses sítios para a base de código sem entender plenamente o funcionamento. Hoje piorou – o povo chupa da IA códigos grandes sem entender nada de como funciona. Menos conhecimento ainda do código que a pessoa terceirizou, e maior chance de erros (IA usando fontes ruins) e alucinações (IA fantasiando).

A seguinte entrevista de Jeremy Howard traz excelente perspectiva sobre o uso responsável de IA: https://youtu.be/LrFbxIvsipw

Entrevista com Jeremy Howard

Jeremy é CEO da Fast.ai e da Answer.ai. Criou o primeiro LLM – Large Language Model, ou modelo de linguagem de grande escala. Esse modelo, chamado ULMFiT, mostrou que o deep learning (aprendizagem profunda) funcionava muito bem com linguagem natural, e foi a base do ChatGPT (hoje temos Deep Seek).

No vídeo ele contesta a empolgação com agentes de IA (AI agents). Contesta a ideia de que a IA fará tudo para as pessoas. Argumenta que quem mergulha em agentes pára de aprender. Não pratica suas habilidades. Terceiriza tudo. Jeremy pretende estar no grupo de pessoas que usa IA com muito cuidado para continuar melhorando suas habilidades. Ele usa IA para se aprimorar, ganhar competência, aprender mais, praticar melhor.

Pessoas estão esquecendo como trabalhar. Estão esquecendo que conseguem trabalhar. Se a IA não resolve, ficam perdidas. Isso faz mal à psique. Quem deveria programar software, usa IA para criar milhares de linhas de código que não entende. Isso acumula dívida tecnológica, tornando muito difícil a depuração de defeitos e a integração. Jeremy já viu pessoas se tornarem deprimidas percebendo que perderam a competência e o controle. A abordagem centrada em agentes de IA coloca o computador no controle. Quem faz isso se coloca no caminho de se tornar incompetente e obsoleto.

O uso cego de IA pode aumentar no curto prazo o volume de trabalho, mas reduz a produtividade real a longo prazo. Código fonte gerado por IA não é muito bom. Não é bem integrado. Não cria camadas de abstração que funcionam bem em conjunto. A boa engenharia de software faz a produtividade aumentar ao longo do tempo. Com código gerado por IA ocorre o oposto. Jeremy avalia que empresas que se apoiam cegamente em IA vão olhar para trás e perceber que, no esforço de sempre conseguir resultado rápido em duas semanas, destruíram sua competência organizacional de criar coisas que duram.

Jeremy propõe que a IA observe o trabalho humano, dê dicas e responda perguntas de modo a guiar nosso trabalho, ao invés de executá-lo. Ele avalia ser um desenvolvedor de software muito melhor do que dois anos atrás, pois se dedica a usar IA para se aprimorar. Quer superar a IA.

Jeremy também apoia fortemente o código aberto, inclusive na IA, pelo bem da democracia. O poder deve ser decentralizado e não concentrado nas mãos dos ricos e poderosos. O Estado precisa intervir. Instituições privadas têm um papel de aproveitar os mercados.

No momento a China é o país que está nos salvando da centralização. Hoje todos os melhores modelos de IA de código aberto são chineses. Jeremy passou muito tempo na China, e avalia que lá o sistema investe de verdade em ciência da computação e matemática, e muitas pessoas acreditam na abertura.

Conclusão

Considero que é crítica a habilidade de usar IA de maneira responsável, para aprimorar o trabalhador humano e não substituí-lo. No entanto, falar é mais fácil do que fazer. Assim como sabemos que alimentação balanceada é muito importante para saúde, mas é difícil resistir à tentação de comer fast food e ultraprocessados, também é difícil resistir à tentação de terceirizar o trabalho para IA.

Eu aqui tento conferir e entender o que o Deep Seek diz. Por privacidade instalei também o qwen2.5:3b localmente em um contêiner Podman no meu laptop. Pretendo comprar uma máquina mais parruda para rodar localmente modelos mais poderosos e reduzir o uso de modelos hospedados em outros países. E quando preciso usar modelos hospedados em outros países, dou forte preferência a modelos de código aberto e hospedados em um país amigo como a China.

 
Leia mais...

from in.versos

Lembro... teus sorrisos: alguns tímidos, outros sem nenhuma vergonha, descontraídos, espontâneos.

Lembro teus gestos: singelos, suaves, alegres — passos dançantes, momentos marcantes.

Amiga, conhecida, dama, flor, menina, mulher.

Carisma, paixão, amor.

Música é tua voz, tua existência — poesia.

Nestes versos, faço da lembrança nostalgia, envolta em melancolia.

Saudades de ti, doce menina.

 
Leia mais...

from in.versos

Sou teu, quando me largo no aperto dos teus braços.

Quero ser só teu, quando me afogo em teus lábios.

Sou assim, vendido a todas, mas de uma só.

Quando —

serei assim, somente teu, sobre a cama, junto a ti.

Após, não se sabe. Pouco importa.

Pois serei sempre teu, e unicamente teu, quando entrares e fechares a porta.

 
Leia mais...

from Fure a bolha

#ciencia #jornalismo #historia

Fontes confiáveis

Introdução

Na ciência da computação dizemos em inglês garbage in, garbage out – se a entrada é lixo, a saída é lixo. Isso vale também para argumentação lógica e aprendizado. Conclusões verdadeiras exigem não apenas um método válido mas também fontes confiáveis. Podemos aplicar metaforicamente o ditado “você é o que você come”.

Critério 1: fidelidade a fatos (literatura científica)

Para qualidade de fonte jornalística ou histórica, um critério crucial é fidelidade aos fatos, respeito ao consenso da literatura científica e uso de bons métodos e boas fontes. Isso importa mais que o tamanho e o prestígio do veículo.

Muito me inspira o argumento de Santo Agostinho – um dos maiores doutores da Igreja. Ele, da época do Império Romano, já defendia que os cristãos se informassem bem sobre a ciência secular. Argumentava (parafraseando): quando um infiel ouve um cristão dizer asneiras e barbaridades sobre coisas visíveis, a Igreja perde credibilidade. De fato, quem diz barbaridades até sobre coisas visíveis não tem credibilidade nem para coisas visíveis, nem (muito menos) para coisas invisíveis.

Isso me serve de valiosa analogia para fontes jornalísticas e históricas. Meu ponto forte são as exatas, pois sou formado em engenharia eletrônica e ciência da computação. Penso que as ciências humanas e sociais são mais sutis e mais suscetíveis a controvérsia do que as ciências exatas. Então quem diz asneiras e barbaridades até sobre as exatas, que dirá das humanas? Quando a cegueira ideológica não poupa nem as exatas, aquela fonte não é confiável nem para exatas, e muito menos para humanas e sociais.

Por exemplo, quem nega a ciência climática perde a credibilidade.

Critério 2: autoridade

Normalmente, quem consulta um cardiologista renomado não exige as fontes (artigo científico, livro etc) quando ele diagnostica pressão alta. Da mesmo forma, um especialista em determinado assunto fala com autoridade sobre aquele assunto. Já um anônimo tem necessidade reforçada de mostrar boas fontes para suas principais alegações controversas. Das fontes sugeridas abaixo, o sítio Red Sails é pouco conhecido mas ainda assim é confiável, pois veicula artigos de autores bem formados ou cobertos de citações de boas fontes.

Critério 3: enquadramento

O enquadramento (ou framing) é uma arma poderosa. Vai além da factualidade e direciona a seleção, ênfase e apresentação de aspectos de uma realidade, promovendo uma definição particular do problema, uma interpretação causal, uma avaliação moral ou uma recomendação de conduta.

Não se trata apenas do que é noticiado, mas como. A escolha de palavras, a voz gramatical (ativa ou passiva), a atribuição (ou não) de autoria e a adjetivação criam um “quadro” mental que induz a interpretação do leitor. Um mesmo acontecimento pode ser enquadrado como “ataque brutal” ou “auto defesa”.

A seguir, contrastamos manchetes do jornal estadunidense The New York Times, ilustrando a diferença drástica de enquadramento conforme os interesses geopolíticos dos Estados Unidos.

Enquadramento desfavorável e atributivo

The New York Times: Russia Strikes Children’s Hospital in Deadly Barrage Across Ukraine

Russia Strikes Children’s Hospital in Deadly Barrage Across Ukraine

Para um adversário dos EUA, o jornal emprega técnicas para gerar condenação e imputar brutalidade a um responsável específico:

  • Identificação clara do agressor: “Russia Strikes” (“Rússia ataca”). As primeiras palavras da manchete explicitam o responsável pelo ataque.
  • Voz ativa: O emprego da voz ativa (”Russia Strikes”) ressalta a intenção. Apresenta o adversário dos EUA como um ator que escolheu a violência.
  • Linguagem emotiva e conotativa: “Deadly Barrage” (“ataque massivo mortal”). A palavra “barrage” enfatiza um volume massivo e indiscriminado de ataques, enquanto “deadly” enfatiza o custo humano.

Enquadramento favorável e dissociativo

The New York Times: Israel-Hamas War: At Least 25 Reported Killed in Strike on School Building in Southern Gaza

Israel-Hamas War: At Least 25 Reported Killed in Strike on School Building in Southern Gaza

Em contraste gritante, o jornal enquadra o ataque israelense a uma escola palestina empregando técnicas para diluir a responsabilidade e contextualizar o ato de forma favorável:

  • Contextualização que justifica: “Israel-Hamas War” (guerra entre Israel e Hamas). A manchete insere o evento no contexto amplo de uma “guerra”. Isto, por um lado, informa, mas por outro, insinua a normalidade do acontecimento, como se fosse um resultado esperado e inevitável da guerra.
  • Voz passiva e agente oculto: “At Least 25 Reported Killed” (“pelo menos 25 mortos são reportados”). A voz passiva omite o autor do ato. As vítimas (“25”) tornam-se o sujeito gramatical da frase, enquanto o ator das mortes desaparece do texto.
  • Dissociação do agressor: A manchete omite Israel como o autor do ataque. O leitor desatento pode, inclusive, inferir que possa ter sido o Hamas. O jornal descreve o ataque como um evento fortuito.
  • Linguagem técnica e impessoal: “Strike on School Building” (Ataque a Edifício Escolar). Comparado com “Strikes a Children's Hospital in Deadly Barrage”, a linguagem é mais fria e burocrática, minimizando a carga emocional.

Impacto do enquadramento

Os veículos jornalísticos sistematicamente enquadram acontecimentos conforme sua visão de mundo e seus interesses. A cobertura jornalística pode, por meio de escolhas conscientes ou inconscientes, orientar a percepção do público:

  • No primeiro exemplo, o veículo induz o leitor a condenar um agressor claramente identificado por um ato de brutalidade.
  • No outro exemplo, o veículo induz o leitor a registrar um evento trágico, mas sem um agressor claro, num contexto de “guerra” que atenua a responsabilidade.

Reconhecer esses mecanismos é vital para uma leitura crítica da mídia. A honestidade de um veículo vai além da factualidade, mas alcança o enquadramento da realidade:

  • Quem é apresentado como agente de ação e quem é apresentado como sujeito passivo?
  • O que é omitido? O que é enfatizado?
  • Que palavras são escolhidas para influenciar minha percepção?

Sugestões

Abaixo vão algumas sugestões de comunicadores e veículos que respeitam a ciência e, transparentemente, se posicionam à esquerda.

Língua portuguesa

  1. Opera Mundi
  2. Elias Jabbour – Presidente do Instituto Municipal de Urbanismo Pereira Passos. Professor Associado da Faculdade de Ciências Econômicas, do Programa de Pós-Graduação em Ciências Econômicas e do Programa de Pós-Graduação em Relações Internacionais na UERJ. Em 2023–2024 foi Consultor Sênior da Presidência do Banco do BRICS e, de abril de 2006 a fevereiro de 2007, Assessor Econômico da Presidência da Câmara dos Deputados. Graduado em Geografia (1997), Doutor (2010) e Mestre (2005) em Geografia Humana pela USP. Tem experiência em Geografia e Economia com ênfase em Geografia Humana e Econômica, Economia Política, Economia Política Internacional e Planejamento Econômico. Atua principalmente nos temas: China; Socialismo com Características Chinesas; Nova Economia do Projetamento; Categorias de Transição ao Socialismo; Estratégias e Experiências Nacionais e Comparadas de Desenvolvimento; Categoria Marxista de Formação Econômico-Social; e Pensamento Independente de Ignacio Rangel. Vencedor do Special Book Award of China.
  3. José Kobori, importante financista de esquerda
  4. ICL Notícias
  5. Carta Capital

Língua inglesa

  1. Geopolitical Economy Report
  2. Red Sails
 
Leia mais...

from in.versos

Em anexo, no peito; Guardo um retrato que não há

Nos olhos: tatuagem de teus lábios, aos quais sempre vejo

Tenho em mãos a carta que nunca lhe escrevi

Escondido nas sombras — meu amor marginal

Em silêncio, dedico canções

Em distância, beijo-te a boca

E tu me devolves a ti

De peito nu e pés descalços

Delírio!

E noite adentro, me perco no aguardo te te teres em meus braços —

e saborear teu amor amargo

 
Leia mais...

from in.versos

Uma fotografia. O coração dispara e no rosto, um sorriso em esboço.

Enquanto a minh'alma baila, no embalo da canção que é a tua efígie.

 
Leia mais...

from Quadrinistas Uni-vos

No dia 23 de julho lançamos, em nosso blogo e aqui no perfil do Instagram, em conjunto com a FEPAL e o comitê árabe-brasileiro de solidariedade do Paraná, manifestação dirigida à organização da Bienal de Quadrinhos de Curitiba questionando se a vinda de Rutu Modan seria mesmo a melhor ideia, por tratar-se de figura israelense com posições chanceladas pela por Israel, justamente no momento histórico em que vivemos o primeiro genocídio televisionado da história, na Palestina (Gaza), e frente ao qual não cabe apoio tácito pelo silêncio.

Esta manifestação política motivou uma série de ações e discussões que proporcionaram um processo com olhar mais cuidadoso para a questão por parte da organização do evento. Inicialmente, pouco tempo após a manifestação de 23 de julho, a organização se posicionou em nota nas redes sociais (26 de julho), colocando-se abertamente contra o genocídio do povo palestino. Em seguida, o coletivo Quadrinistas Uni-vos foi convidado a participar de uma mesa de diálogo com a organização da Bienal, a FEPAL e o comitê de solidariedade ao povo palestino, onde houve consenso para que o povo palestino ocupasse papel de protagonismo na Bienal e pudesse falar a todos presentes, seja sobre quadrinhos, seja sobre a situação de horror vivida na Palestina, num contraponto à mídia hegemônica brasileira, sócia do regime sionista na empreitada genocida em Gaza.

Essa postura da organização da Bienal, solícita e gentil, além de coerente, permitirá construir uma bienal em que a utopia de um mundo em que o futuro para todos – e, neste momento, especialmente para o povo palestino – seja possível, com paz e justiça, em lugar de um não-futuro de esquecimento e total aniquilação. Que desta Bienal de Curitiba emitamos força para a retomada da paz e da soberania do povo palestino sobre a sua Terra Santa.

Coletivo Quadrinistas, Uni-vos FEPAL – Federação Árabe Palestina do Brasil Comitê Árabe brasileiro de Solidariedade – Paraná Comitê de Solidariedade à Palestina de Curitiba

 
Leia mais...

from Quadrinistas Uni-vos

No dia 12 de maio, em meio à mais recente ofensiva israelense sobre a Palestina, recebemos com surpresa o anúncio de que a Bienal de Quadrinhos de Curitiba traria Rutu Modan, autora israelense de quadrinhos.

Isso, por si só, já configuraria, no mínimo, uma insensibilidade com o momento. Afinal, são 195 países no mundo, 26 estados brasileiros, e a Bienal precisa convidar justamente uma quadrinista de nacionalidade de um país que está realizando um genocídio contra um povo inteiro? E, mais importante: uma quadrinista que não tem uma posição clara sobre isso?

Nos comentários em seu perfil do Instagram, o evento foi questionado, porém a resposta foi um silêncio retumbante. Nesse momento, em que Israel se aproxima de uma “solução final”, em que ativistas estrangeiros levando ajuda humanitária, incluindo um brasileiro, são sequestrados por Israel em águas internacionais, e que Gaza pode ser considerado o lugar mais faminto do mundo, a Bienal optou por ficar em silêncio. Seus organizadores só se manifestaram em suas redes privadas para chamar os protestos de “gritaria de internet”.

Vale ressaltar que, inicialmente, a organização da Bienal foi questionada somente quanto à posição da autora a respeito do genocídio palestino. Não houve insultos ao evento, não foi exigido que desconvidassem a autora – afinal, há israelenses que são vocalmente antissionistas. No entanto, esse não é o caso de Modan – ao contrário, as posições da artista corroboram ainda mais para o fato de que é uma insensatez trazê-la neste momento.

Que se destaque: se as pessoas precisam pesquisar se você é contra um genocídio, talvez você não esteja se posicionando o suficientemente contra ele. A postura da autora é dúbia, sendo difícil definir seu posicionamento através de suas redes sociais, por exemplo.

Como cidadãos da potência ocupante, é imprescindível que israelenses que são contra a ocupação usem sua voz e se posicionem de forma enfática contra o genocídio e o processo de colonização da palestina – até porque, caso não o façam, correm o risco de serem usados como propaganda de Israel, principalmente no caso de artistas.

Em mais de uma entrevista ela reclama do fato de sempre lhe perguntarem primeiro sobre sua posição política, em vez de sobre sua obra. Sejamos honestos: o único motivo pelo qual o cidadão de uma potência ocupante não sente a necessidade de falar sobre o que está acontecendo é porque não é sobre sua cabeça ou na de sua família que estão caindo bombas todos os dias.

Em entrevista ao site “The Comics Journal”, ela diz ser “contra a guerra”, mas que ainda assim “enxerga a complexidade da situação”. Em entrevista ao site brasileiro “O quadro e o risco”, ela afirma que “Pra mim, é interessante mostrar como enxergo a vida aqui. A melhor parte disso é não resolver as coisas, porém mostrar a complexidade delas.” (grifo nosso). No posfácio da edição brasileira da HQ “Túneis”, ela afirma que “a insistência em determinar quem começou nos faz voltar cinquenta setenta cem, seiscentos, 3 mil anos no tempo”, como se fosse uma guerra religiosa, coisa de “malucos” (termo que ela usa para se referir aos personagens “extremistas” de sua HQ no posfácio da edição original, aliás).

Na verdade, a questão não é “complexa”, não começou há 3 mil anos e não tem nada de “maluco”: trata-se de um processo de colonização, que existe porque Israel é uma potência ocupante e genocida desde 1947, ano da primeira Nakba.

No mesmo texto, Modan afirma sobre as “narrativas (..) usadas como justificativa por cada um dos lados para a aniquilação do outro”. Os palestinos não querem “aniquilar” ninguém. Querem, sim, o fim da ocupação e a chance de retornar às suas terras e viver uma vida digna. O único “lado” que tem um discurso de aniquilação é Israel.

A autora tenta claramente vender a ideia de que os dois lados seriam iguais e de que o estado de apartheid não existiria – e, com uma boa retórica, busca equiparar o Estado invasor e a população do território invadido. A ideia de que seriam “dois lados” que desejariam igualmente o extermínio um do outro ignora o fato de que, de um lado, há um Estado armado até os dentes – com mísseis, um forte aparato militar, apoio militar internacional e uma maioria de soldados treinados-, enquanto do outro há apenas um povo que é sistematicamente agredido, um povo cujo direito a viver na própria terra lhe é negado, mas que resiste.

Ressaltamos aqui que o direito à resistência armada de um povo sob o jugo do colonialismo é reconhecido e regulamentado pela resolução 38/17 da Assembleia Geral da ONU de 1983. Mas, mesmo essa resistência armada não pode ser comparada militarmente com o poderio isrelense. A realidade é que o que estamos vendo hoje tem nome e sobrenome: colonialismo e genocídio.

Vale lembrar, ainda, que o posfácio citado foi escrito em outubro em 2024, UM ANO após os ataques de 07 de outubro de 2023, época em que já haviam sido assassinados mais de 40 mil palestinos e Israel já havia jogado em gaza mais bombas do que os bombardeios da Segunda Guerra Mundial em Dresden, Hamburgo e Londres juntos. Ainda assim, a autora parece ter alergia à palavra “genocídio”, e insiste na narrativa de “guerra” e “dois lados que se odeiam”, como se bastassem ambos deixarem de lado suas “maluquices” e dar as mãos para, então, reinar a paz.

Rutu Modan pode não querer que israel acabe totalmente com a Palestina, mas suas colocações desumanizam o povo palestino e retiram dele o direito à resistência.

Daqui a alguns anos, algumas pessoas vão dizer “eu não sabia o que fazer”. Mas nós sabemos, os palestinos estão nos dizendo o que fazer: demonstrar solidariedade, isolar Israel, fazer parar o genocídio. Trata-se portanto, de outra questão: o que QUEREMOS fazer?

Não há possibilidade de silêncio frente ao genocídio do povo palestino. Por isso, deixamos aqui nosso repúdio a essas posições supostamente neutras da autora e, ainda, à postura do evento, que não faz jus ao tema deste ano, “Futuros possíveis”. Só há futuro para a Palestina com o fim do colonialismo e da matança feitos por Israel.

Seguimos na luta por uma Palestina livre, do rio ao mar.

Coletivo Quadrinistas, Uni-vos FEPAL – Federação Árabe Palestina do Brasil Comitê Árabe brasileiro de Solidariedade – Paraná Comitê de Solidariedade à Palestina de Curitiba

 
Leia mais...