Bolhaverso

Reader

pt-br

Leia os posts do bolha.blog.

en-us

Read all posts from our users.

from in.versos

Dá-me de comer aos vermes. Que eles se empanturrem com minha carne podre.

Que devorem olhos e língua — pois já não preciso deles senão para vê-la e lisonjeá-la.

Que se fartem de meu coração — pois já não necessito viver, tampouco sentir.

Mas antes de voltar ao pó terei primeiro eu que sucumbir.

Não te preocupes em sujar as mãos — essa tarefa cumprirei eu mesmo:

afogando-me em goles de poesias e garrafas de desejo.

 
Leia mais...

from Riverfount

Este artigo aborda como usar funcionalidades avançadas de tipagem em Python, como Protocols, Generics e técnicas avançadas de typing, para criar aplicações escaláveis, flexíveis e de fácil manutenção.

Protocols: Contratos Flexíveis e Estruturais

Protocols permitem definir contratos de métodos e propriedades sem herança explícita, facilitando a interoperabilidade entre microserviços. Qualquer classe que implemente os métodos definidos no protocolo pode ser usada onde esse protocolo é esperado.

Exemplo prático:

from typing import Protocol

class Serializer(Protocol):
    def serialize(self) -> bytes:
        pass

class JsonSerializer:
    def serialize(self) -> bytes:
        return b'{"user": "alice"}'

class XmlSerializer:
    def serialize(self) -> bytes:
        return b'<user>alice</user>'

def send_data(serializer: Serializer) -> None:
    data = serializer.serialize()
    print(f"Enviando dados: {data}")

send_data(JsonSerializer())
send_data(XmlSerializer())

Neste exemplo, send_data aceita qualquer objeto que implemente o método serialize, garantindo baixo acoplamento e flexibilidade.

Generics: Componentes Reutilizáveis e Tipados

Generics permitem criar classes e funções genéricas que mantêm a segurança de tipos, facilitando a modularidade.

Exemplo de repositório genérico:

from typing import TypeVar, Generic, List

T = TypeVar('T')

class Repository(Generic[T]):
    def __init__(self) -> None:
        self._items: List[T] = []

    def add(self, item: T) -> None:
        self._items.append(item)

    def get_all(self) -> List[T]:
        return self._items

class User:
    def __init__(self, username: str) -> None:
        self.username = username

user_repo = Repository[User]()
user_repo.add(User("alice"))
for user in user_repo.get_all():
    print(user.username)

Este padrão permite criar repositórios ou caches que funcionam com qualquer tipo de objeto, aumentando a reutilização e segurança de tipos.

Tipagem Avançada: Operador | e Literal

Prefira o operador | para tipos alternativos ao invés de Union e use Literal para valores fixos, reforçando contratos claros.

Exemplo:

from typing import Literal

def login(role: Literal['admin', 'user', 'guest']) -> str:
    if role == 'admin':
        return "Acesso total"
    elif role == 'user':
        return "Acesso limitado"
    return "Acesso restrito"

print(login('admin'))  # Acesso total

Isso aumenta a legibilidade e reduz riscos de erro nas chamadas de função.

Conclusão

Combinando Protocols, Generics e tipagem avançada, é possível construir aplicações com contratos claros, flexíveis e robustos, facilitando o trabalho em times desacoplados e a manutenção do código.

Essas práticas elevam a qualidade do código e tornam os sistemas mais escaláveis e confiáveis, sendo indispensáveis para desenvolvedores focados em arquiteturas modernas, principalmente as de microserviços.

 
Read more...

from Riverfount

Você já enfrentou resultados inesperados ao usar listas ou dicionários como valores padrão em funções Python? Esse é um problema comum que pode causar bugs sutis e difíceis de encontrar. Neste artigo técnico, vamos desmistificar o motivo desse comportamento, mostrando exemplos práticos e como evitá-lo com boas práticas de programação. Se você é um desenvolvedor Python buscando produzir código mais robusto e previsível, este conteúdo é essencial para o seu dia a dia.

Evitando Surpresas

Ao definir funções em Python, usar valores padrão em argumentos é comum para facilitar chamadas. Contudo, quando o valor padrão é um tipo mutável, como listas ou dicionários, isso pode causar efeitos inesperados. Vamos analisar exemplos para entender esse comportamento.

Exemplo Problemático: Lista Mutável como Valor Padrão

def add_item(item, lista=[]):
    lista.append(item)
    return lista

print(add_item('maçã'))    # Saída esperada: ['maçã']
print(add_item('banana'))  # Saída inesperada: ['maçã', 'banana']

Aqui, o segundo print adiciona o item 'banana' à mesma lista usada na primeira chamada, porque o objeto lista padrão foi criado uma vez e reutilizado. Isso acontece porque argumentos padrão são avaliados apenas na definição da função.

Corrigindo com None como Valor Padrão

A forma recomendada é usar None e criar a lista dentro da função quando necessário:

def add_item(item, lista=None):
    if lista is None:
        lista = []
    lista.append(item)
    return lista

print(add_item('maçã'))    # Saída: ['maçã']
print(add_item('banana'))  # Saída: ['banana']

Assim, cada chamada sem lista passa a criar uma nova lista vazia, evitando efeitos colaterais.

Mais um Exemplo com Dicionário Mutável

def increment_count(key, counts={}):
    counts[key] = counts.get(key, 0) + 1
    return counts

print(increment_count('python'))  # {'python': 1}
print(increment_count('java'))    # {'python': 1, 'java': 1} – resultado inesperado

No caso acima, o dicionário padrão é compartilhado e mantido entre as chamadas. A forma correta:

def increment_count(key, counts=None):
    if counts is None:
        counts = {}
    counts[key] = counts.get(key, 0) + 1
    return counts

print(increment_count('python'))  # {'python': 1}
print(increment_count('java'))    # {'java': 1}

Exemplo com Classe e Argumento Mutável

class Collector:
    def __init__(self, items=[]):
        self.items = items

    def add(self, item):
        self.items.append(item)

    def get_items(self):
        return self.items

c1 = Collector()
c1.add('foo')

c2 = Collector()
print(c2.get_items())  # Saída inesperada: ['foo']

A mesma lista é compartilhada por todas as instâncias quando passada como valor padrão mutável. Correção:

class Collector:
    def __init__(self, items=None):
        self.items = items or []

    def add(self, item):
        self.items.append(item)

    def get_items(self):
        return self.items

c1 = Collector()
c1.add('foo')

c2 = Collector()
print(c2.get_items())  # Saída correta: []

Boas Práticas para Evitar Problemas com Argumentos Mutáveis

  • Nunca use tipos mutáveis como valores padrão de argumentos. Prefira usar None e inicialize a variável dentro da função.

  • Evite efeitos colaterais em funções. Funções devem ser previsíveis e sempre retornar resultados baseados em seus argumentos.

  • Prefira tipos imutáveis para valores padrão. Imutáveis como int, str e tuple não causam esse tipo de problema.

  • Ao lidar com objetos mutáveis, clone-os quando necessário. Use métodos como copy() ou slicing para evitar alterações inesperadas.

  • Teste cuidadosamente funções que recebem parâmetros opcionais. Garanta que o estado de chamadas anteriores não afete as subsequentes.

  • Documente o comportamento esperado de seus métodos, especialmente em bibliotecas e APIs. Indique claramente se objetos mutáveis são compartilhados ou não.

Dominar essas técnicas ajuda a produzir código Python mais resiliente e menos propenso a bugs difíceis de detectar, essencial para engenheiros de software que buscam qualidade profissional em seus projetos.

 
Read more...

from in.versos

Cruzamos nossos olhares e nossas mãos

Entrelaçamos nossos corpos — nos braços um do outro

Subi um degrau e ela desceu mais um

Encontro!

(Os lábios dela nos meus)

Foi rápido

Ela já não estava ali quando o meu corpo estremeceu e minha alma dançou

Surpreso, sorri

E naquela noite decretei que era amor aquele arrepio na espinha

 
Leia mais...

from in.versos

Há dois tipos de desejo: o da carne e o da alma.

Não são opostos — pelo contrário, é quando ambos se manifestam juntos que o fervor da paixão se torna súplica do amor.

Se em teu sorriso me perco e tua forma desejo, é no silêncio do teu olhar, nos teus gestos ao andar, na alegria do teu estar, na musicalidade do teu falar, na intensidade do teu existir — que me entrego por inteiro.

 
Leia mais...

from Riverfount

Entenda os riscos do uso de from módulo import * em Python, saiba por que ele compromete a legibilidade e a manutenção do código e descubra as alternativas recomendadas por desenvolvedores experientes.

A armadilha da conveniência em Python

Há algo em Python que seduz até os desenvolvedores mais experientes: a promessa de simplicidade. Poucas linguagens conseguem equilibrar legibilidade e poder expressivo como ele faz. Mas é justamente essa aparente simplicidade que, às vezes, nos leva a atalhos perigosos. Entre eles, um velho conhecido: from módulo import *.

Essa linha, tão curta quanto tentadora, parece inofensiva em pequenos scripts… até que o projeto cresce, outros módulos entram em cena e o caos começa a se insinuar. O que parecia elegante se transforma em um labirinto de dependências invisíveis, nomes sobrescritos e bugs indecifráveis.

A falsa sensação de simplicidade

Importar tudo de um módulo é como abrir as portas da sua casa e deixar qualquer um entrar. De início, parece acolhedor. Mas quando algo dá errado, você não sabe quem fez a bagunça. Essa é a essência do problema: o código perde fronteiras claras.

Quando um projeto cresce, inevitavelmente surgem conflitos de nome. Uma função sua pode ter o mesmo nome de algo importado, e lá se vai a previsibilidade do comportamento do código. E o pior: o erro nem sempre se manifesta de forma imediata — ele se infiltra sutilmente, como um bug fantasma que só aparece na pior hora possível.

Legibilidade acima da brevidade

Um código é tão bom quanto sua capacidade de ser compreendido por outras pessoas (inclusive você no futuro). Ao usar import *, você apaga pistas valiosas sobre de onde vêm as funções que usa. Quando um leitor se depara com sqrt(16), ele precisa adivinhar: é uma função da biblioteca padrão, algo definido localmente ou algo importado de um módulo obscuro?

Essa incerteza sabota um princípio essencial de engenharia: previsibilidade. Códigos que exigem adivinhações são códigos menos confiáveis.

Custo oculto e impacto no código

O uso de from módulo import * não implica em maior custo de desempenho ou tempo de carregamento. Ao importar um módulo, o interpretador Python o carrega e inicializa apenas uma vez, armazenando-o em sys.modules. As importações subsequentes, com ou sem *, apenas criam novas referências aos objetos já existentes.

O verdadeiro impacto está na legibilidade e manutenção. A importação global adiciona múltiplos nomes ao namespace atual, podendo sobrescrever identificadores e dificultar a rastreabilidade das dependências. Isso reduz a previsibilidade do código e aumenta o risco de colisões de nomes e efeitos colaterais sutis, principalmente em bases de código extensas.

Em projetos de médio e grande porte, recomenda-se sempre preferir importações explícitas (import módulo ou from módulo import símbolo) para preservar a clareza e facilitar ferramentas de análise estática, refatoração e autocompletar em IDEs.

Alternativas seguras e idiomáticas em Python

A boa notícia é que a linguagem oferece opções mais claras — e alinhadas com a filosofia “Explicit is better than implicit”:

from math import sqrt, pi

Importe apenas o que você precisa e comunique intenção.

Ou, se preferir manter a origem explícita:

import math
resultado = math.sqrt(16)

A notação com ponto reforça a origem de cada função.

E em casos de bibliotecas extensas, os alias ajudam:

import pandas as pd
df = pd.read_csv("data.csv")

Essa convenção é legível, padronizada e amplamente aceita pela comunidade.

Um sinal de maturidade profissional

Código limpo não é o mais curto, e sim o mais claro. Evitar import * é um passo em direção à maturidade profissional. É escolher clareza e previsibilidade no lugar da pressa.

Em tempos em que a maioria dos bugs surge nas fronteiras entre módulos, saber exatamente de onde cada símbolo vem não é luxo — é controle.

Um convite à reflexão

Na próxima vez que você digitar from módulo import *, pause. Pergunte-se se a conveniência justifica o custo. O Python recompensa quem escolhe caminhos explícitos. E talvez o maior sinal de evolução como engenheiro Python seja perceber que clareza é o verdadeiro atalho.

🧭 Boas práticas resumidas

  • Prefira importações explícitas (from math import sqrt, pi).
  • Use alias padronizados em bibliotecas populares (import pandas as pd, import numpy as np).
  • Evite nomes genéricos que possam colidir com funções de módulos.
  • Documente qualquer alias ou importação incomum no projeto.
  • Faça revisões periódicas no código para eliminar usos antigos de import *.
  • Valorize a clareza: código previsível é sinônimo de código profissional.
 
Read more...

from Riverfount

No desenvolvimento Python, especialmente em projetos de médio a grande porte e pipelines complexos de testes automatizados, é comum encontrar erros sutis relacionados a comparações com o valor booleano True. Uma prática aparentemente inofensiva, como usar == True para verificar condições, pode introduzir comportamentos inesperados que dificultam a manutenção, geram falsos positivos em testes e causam dúvidas em revisões de código.

Essas situações não são incomuns em equipes que lidam com múltiplas camadas de abstração — desde o código de negócio até frameworks de teste — e evidenciam a importância de entender profundamente a diferença entre identidade e igualdade em Python, bem como as melhores práticas para escrever condicionais claras e robustas.

Entendendo o impacto de is True vs == True

O operador is verifica se dois objetos são exatamente os mesmos na memória — ou seja, se têm identidade. No caso de var is True, o teste passa somente se var for exatamente o objeto singleton True do Python.

Já o operador == compara valores, permitindo que diversos objetos considerados “truthy” no contexto booleano, como 1, Strings não vazias ou listas, sejam equivalentes a True quando comparados com var == True. Isso pode causar falhas silenciosas ou testes que passam indevidamente.

if 1 == True:  # Avalia para True, embora 1 não seja o objeto True
    print("Isso pode confundir a lógica.")

Esse tipo de resultado pode mascarar bugs ou comportamentos inesperados, especialmente em testes unitários.

Evitando comparações explícitas desnecessárias

O consenso na comunidade Python — refletido em PEP8 e amplamente adotado — é que a maioria das comparações explícitas com True e False são redundantes e prejudicam a legibilidade. Python permite confiar diretamente na avaliação booleana implícita, que é mais limpa e expressiva.

# Menos legível
if var == True:
    ...

# Idiomático
if var:
    ...

# Para casos False
if not var:
    ...

Essa abordagem reduz o ruído visual e elimina ambiguidades causadas por diferentes tipos que avaliam para verdadeiro ou falso.

Exemplos práticos de erros comuns

  • Erro em comparações com listas booleanas:
a = [True, True, False]
b = [True, True, True]

result = a and b  
print(result)  # Saída: [True, True, True]

Aqui, usar and entre listas não faz uma comparação elemento a elemento, mas retorna o último valor avaliado. Isso pode levar a resultados inesperados, especialmente se se esperava um valor booleano.

  • Confusão com tipos de retornos em bibliotecas como NumPy:

Em NumPy, comparações booleanas não retornam True ou False do Python nativo, mas tipos como np.True_ ou np.False_, que podem quebrar testes que usam is True:

import numpy as np

result = np.array([1, 2, 3]) == 1
print(result)          # array([ True, False, False])
print(result[0] is True)  # False, pois é np.bool_, não bool nativo

Essa sutileza é fonte comum de bugs em projetos científicos e de análise de dados.

  • Falsos positivos em testes unitários:
def test_func():
    result = 1
    assert result == True  # Passa, mas result não é booleano

    assert result is True  # Falha, aqui a precisão salva o teste

O uso de is True impede que valores “truthy” como 1 passem em testes que esperam tipos booleanos.

Casos excepcionais: validação rigorosa em testes unitários

Há, todavia, situações específicas — especialmente em testes unitários — onde a precisão semântica é necessária. Quando uma função ou método deve retornar explicitamente o valor booleano True, e não apenas um “valor truthy” qualquer, o uso de assert ... is True garante que o teste falhe se houver qualquer discrepância de tipo ou valor.

def is_even(number):
    return number % 2 == 0

def test_is_even():
    result = is_even(4)

    # Verificação rigorosa: valida identidade
    assert result is True

    # Evitar
    assert result == True

Essa prática ajuda a prevenir falsos positivos em pipelines de CI/CD, assegurando que o comportamento funcional esperado esteja alinhado com tipos e valores corretos e não somente com avaliações booleanas superficiais.

Conclusão: clareza e rigor em equilíbrio

Escrever código Python robusto é também dominar as sutilezas da linguagem. Evitar comparações explícitas desnecessárias com True não só melhora a clareza, como também reduz riscos de bugs ocultos.

Por outro lado, saber quando estabelecer verificações estritas, como em testes unitários com is True, demonstra maturidade técnica e compromisso com a qualidade.

Equilibrar legibilidade e precisão é o passo decisivo que diferencia código “funcional” de código profissional, limpo e confiável.

 
Read more...

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 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 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...