Python: Strings e Codificação


Outras informações sobre Strings

Aviso: Se você está lendo essas notas pela primeira vez essas informações podem ser consideradas um pouco complexas. É recomendável que você pule essa seção e volte a ela mais tarde.

Strings são variáveis usadas para armazenar texto. Nessas notas elas já foram estudadas na seção Python: Strings. Algumas informações adicionais podem ser úteis.

Prefixos Modificadores de Strings

Além das strings usuais é possível usar modificadores por meio de prefixos para representar coisas diferentes no Python. As strings resultantes são objetos de string, como qualquer outra string, admitindo seus métodos e propriedades. O prefixo f é o mais comum, permitindo a avaliação de expressões dentro de uma string. Além dele podemos mencionar outros prefixos que podem ser usados sozinhos ou em conjunto:

  • b: bytes literais
  • f: string formatada
  • r: strings brutos
  • u: string usando Unicode legado (PEP 414)

As f-strings são de uso muito comum no Python, que permitindo avaliar expressões dentro de literais de string. As strings brutas não são tão populares quanto as f-strings mas têm seus próprios usos, importantes em certas ocasiões. Resumidamente elas ignoram sequências de escape e retornam texto puro. Strings de bytes são necessárias para armazenar objetos que não contém apenas caracteres mas também códigos de controles e outros valores binários. Unicode legado serve para expressar string em sistemas antigos que ainda não tinham o UTF-8 incorporado.

Strings e bytes

O Python tem o datatype bytes, uma classe diferente das strings.

» string1 = 'Python Pool' 
» print(type(string1))  
↳ <class 'str'>

» string2 = b'Python Pool' 
» print(type(string2)) 
↳ <class 'bytes'>

Método bytes(): O método bytes() converte strings em bytes, retornando um objeto imutável. Seu construtor pode receber o conteúdo da string e sua codificação.

» texto = "Podemos converter strings em bytes"
# converta string em bytes
» texto_to_byte = bytes(texto, 'utf-8')
» print(texto_to_byte)
# Output:
↳ b'Podemos converter strings em bytes'

Lembrando: Nos blocos de código nesse site usamos a notação » para linhas de código, para resuktados (outputs) e # para comentários do Python.

O método bytes(texto, 'utf-8') converte a string em um objeto bytes usando a codificação utf-8.
Também é possível passar apenas o tamanho da variável, ou uma lista (um iterável):

» tamanho = 7
» bvar = bytes(tamanho)
» print(bvar)
# Output
↳ b'\x00\x00\x00\x00\x00'

» lista = [1, 2, 3, 4, 5]
» bvar = bytes(lista)
» print(bvar)

# Output
↳ b'\x01\x02\x03\x04\x05'

As saídas contém os números de entrada transformados para o formato hexadecimal: 0 &arr;\x00, …, 5 &arr;\x05, etc.

Método decode(): O método inverso, para receber entradas em formato codificado e retornar o argumento decodificado em uma string comum é decode().

» st1 = b'Decodificar \xE2\x9C\x85'
» st2 = b'Decodificar \xE2\x9B\x85'
» print(st1.decode("utf-8"))
↳ Decodificar ✅
» print(st2.decode("utf-8"))
↳ Decodificar ⛅

Nesse caso decode() converteu bytes em strings. Nesse exemplo o código utf-8 \xE2\x9C\x85 representa o sinal ✅ enquanto \xE2\x9B\x85 é o código para o sinal ⛅.

Método chr(): O método chr() converte um inteiro no caracter unicode correspondente.

» print("Usando chr(int):")
» print(f"Maiúsculas: chr(65) = {chr(65)}, ..., chr(90) = {chr(90)}")
» print(f"Minúsculas: chr(97) = {chr(97)}, ..., chr(122) = {chr(122)}")
    
↳ Usando chr(int):
↳ Maiúsculas: chr(65) = A, ..., chr(90) = Z
↳ Minúsculas: chr(97) = a, ..., chr(122) = z

Strings formatadas

Iniciando com o Python 3.12 passou a ser permitido usar strings formatadas, ou f-strings. Elas são uma forma de inserir avaliações de código dentro de texto, concatenando literais de strings com o resultado.

» idade_1 = 15
» idade_2 = 19
» print(f"A idade somada de nossos alunos é {idade_1 + idade_2}, com média {(idade_1 + idade_2)/2}.")
↳ 'A idade somada de nossos alunos é 34, com média 17.0.'

» aluno = {"nome": "Jean Paul", "sobrenome": "Dirac" ,"area": "Física"}
» print(f"Nosso aluno {aluno["nome"]} {aluno["sobrenome"]} se destacou em {aluno["area"]}!")
↳ 'Nosso aluno Jean Paul Dirac se destacou em Física!'

# uma forma mais compacta de conseguir o mesmo resultado consiste em usar 
» aluno = {"nome": "Jean Paul", "sobrenome": "Dirac" ,"area": "Física"}
» print("Nosso aluno {nome} {sobrenome} se destacou em {area}!".format(**aluno))
↳ 'Nosso aluno Jean Paul Dirac se destacou em Física!'


No último exemplo usamos os nomes dos campos diretamente e passamos a string para o método string.format(**aluno). Como argumento o operador ** de desempacotamento (unpacking) retorna os valores do dicionário, ignorando campos extras, caso existam. Essa última forma é mais concisa e legível.

Strings brutas

Strings brutas (raw strings) tem um comportamento igual ao de uma string literal normal, com uma diferença importante: elas ignoram quaisquer sequências de caracteres de escape contidas na string. Por exemplo:

» print("1 - Componentes do átomo:\n\t Prótons \n\t Nêutrons \n\t Elétrons")
↳ 1 - Componentes do átomo:
       Prótons 
       Nêutrons 
       Elétrons

» print(r"2 - Componentes do átomo:\n\t Prótons \n\t Nêutrons \n\t Elétrons")
↳ 2 - Componentes do átomo:\n\t Prótons \n\t Nêutrons \n\t Elétrons

No primeiro caso os carateres de controle \n e \t, respectivamente newline e tab, são interpretados como controles. No segundo caso os controles são representados literalmente, como strings.

Se nenhum caracter de controle for encontrado a string fica inalterada com o prefixo r.

» print(r"É muito legal programar com python!" == "É muito legal programar com python!")
↳ True

# mas...
» print(r"10\25\1991" == "10\25\1991")
↳ False

regex
Esse tipo de recurso é particularmente útil quando usamos expressões regulares. Nelas são passadas aos métodos parâmetros com strings incluídas barras invertidas, que têm significado especial para as regex, sem necessidade de escape. Você pode ler sobre as expressões regulares em Expressoes Regulares no Python e, no caso geral, Expressoes Regulares.

Raw strings também auxiliam na construção de caminhos de arquivos e diretórios que contêm barras invertidas que não devem ser “escapadas”. Finalmente elas são úteis para exibir strings com caracteres difíceis de digitar ou ler, caracteres de controle como nova linha ou tabulações.

Codificações de caracteres em Python

Para representar caracteres e sinais de controle no computador diversos sistemas de codificação foram criados. Uma codificação é um sistema de traduzir caracteres (letras, pontuações, símbolos, espaços em branco e controle) para números inteiros e posteriormente para bits.

O mais simples deles é o sistema ASCII, que usa apena 1 byte em toda a sua codificação. Isso pode ser confirmado com a operação:

» all(len(chr(i).encode("ascii")) == 1 for i in range(128))
↳ True

o que mostra que todos os caracteres em chr(i).encode("ascii") com i = 0 … 127 tem comprimento 1.
Tabela ASCII resumida:

Código representa
0 até 31 caracteres de controle, não imprimíveis,
32 até 64 pontuação, símbolos, núeros e espaço,
65 até 90 caracteres maiúsculos do alfabeto inglês,
91 até 96 sinais gráficos como [ \ ] ^ _ `,
97 até 122 caracteres minúsculos do alfabeto inglês,
123 até 126 sinais gráficos adicionais como { | } ~,
127 controle de apagamento (del) não imprimível.

No entanto, o sistema de codificação ASCII permite apenas o mapeamento de 127 sinais ou controles. Ele é pequeno demais para representar a variedade de caracteres acentuados, além daqueles usados em outras línguas como chinês e russo. Por isso se desenvolveu um sistema capaz de representar um conjunto muito maior de caracteres e sinais, de denominado Unicode. Muitos outros sistemas foram criados entes dele mas é predominante, hoje o uso do Unicode e um de seus esquemas de codificação, o UTF-8. Por motivo de compatibilidade os primeiros 127 códigos coicidem com os do ASCII



O Unicode não é um sistema de codificação mas engloba vários deles. Ele mapeia caracteres como “a”, “¢” ou “😎”, incluindo emojis. Ele contém praticamente todos os caracteres necessários para uma comunicção moderna internacional, incluindo a marca (código 8207) que indica que o texto será exibido da direita para a esquerda, usado em línguas árabes.

UTF-8: Para representar essa diversidade de caracteres, sinais e controles surgiu o UTF-8, que usa mais de 1 bite na codificação. Seu código tem comprimento variável para cada sinal, podendo chegar a até 4 bites. Por default o Python usa a codificação utf-8.

O código abaixo mostra um caracter, um emoji, com comprimento 4 nessa codificação.

» emoji = "🤨"
» print(len(emoji))
↳ 1
» print(emoji.encode("utf-8"))
↳ b'\xf0\x9f\xa4\xa8'
» print(len(ibrow.encode("utf-8")))
↳ 4

# construir uma lista com objeto de bytes retorna
# o valor decimal para cada byte
» print(list(b'\xf0\x9f\xa4\xa8'))
↳ [240, 159, 164, 168]

Nota, é importante lembrar: o comprimento de um único caracter em unicode no Python é 1, mesmo que ele ocupe vários bites. O comprimento desse caracter codificado em bytes será entre 1 e 4, no UTF-8.

Funções associadas do Python

O Python tem várias funções internas (built-in) associadas com systemas de numeração e codificação de caracteres:

Função retorna
ascii(objeto) string, representação ASCII do objeto com caracteres não-ASCII escapados,
bin(inteiro) string, representação binária do inteiro com prefixo “0b”,
bytes(iterável) converte para bytes, dados binários brutos,
chr(inteiro) string, caracter unicode,
hex(inteiro) string, representação hexadecimal com prefixo “0x”,
int(número) inteiro, converte para inteiro,
oct(número) inteiro, converte para número octal com prefixo “0o”,
ord(string) inteiro, converte caracter unicode para inteiro,
str(objeto) converte para string, texto.

Alguns exemplos:

» print(ascii("jalapeño"))
↳ "'jalape\\xf1o'"

» print(bin(400))
↳ '0b110010000'

» print(bytes(range(97, 123)))  # Iterável de inteiros
↳ b'abcdefghijklmnopqrstuvwxyz'

» print(chr(1114111))
↳ '\U0010ffff'

» print(hex(100))
↳ '0x64'

» print(int('11', base=2))
↳ 3

» print(ord("a"))
↳ 97

» print(str(5))
↳ '5'

» print(str(0xc0ffee))
↳ '12648430'

Módulo String

O Módulo de Strings vem pre-instalado no Python, contendo constantes e método úteis, e duas classes.

String, constantes:

» import string

# string module constants
» print(string.ascii_letters)
↳ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

» print(string.ascii_lowercase)
↳ abcdefghijklmnopqrstuvwxyz

» print(string.ascii_uppercase)
↳ ABCDEFGHIJKLMNOPQRSTUVWXYZ

» print(string.digits)
↳ 0123456789

» print(string.hexdigits)
↳ 0123456789abcdefABCDEF

» print(string.whitespace)  # ' \t\n\r\x0b\x0c'

» print(string.punctuation)
↳ !"#$%&'()*+,-./:;?@[\]^_`{|}~

Método capwords(): O módulo possui um único método, capwords(texto, sep=None). Ela quebra a string em texto, transforma em maiúscula a primeira letra de cada palavra e as junta na string de retorno. Se o argumento opcional sep="None" espaços em branco nas extremidaddes são removidos. Se outro sep é fornecido ela é usado para quebrar o texto original.

» import string
» texto = "  venha aprender o \n\n python  "
» print(string.capwords(texto))
↳ "Venha Aprender O Python"

Classe Formatter: O módulo string possui também duas classes. A classe Formatter tem o mesmo comportamento que string.format() mas é útil para ser herdada em uma classe nova do usuário que define formatação personalizada.

» from string import Formatter
» formatter = Formatter()
» print(formatter.format('Um bom site é {site}', site='Phylos.net.'))
↳ 'Um bom site é Phylos.net.'

# variáveis podem ser posicionais e nomeadas
» print(formatter.format('{} {site}', 'Visite nosso site: ', site='Phylos.net.'))
↳ 'Visite nosso site: Phylos.net.'

# O método de string "format()" tem o mesmo comportamento
» print('{} {site}'.format('Leia sobre vários tópicos em ', site='Phylos.net.'))
↳ 'Leia sobre vários tópicos em Phylos.net.'

Método Template: A outra classe de Formatter é Template, útil para a produção de aplicativos internacionalizados, onde um marcador informa a posição onde texto posterir será inserido.

» from string import Template
» temp = Template('Em $lingua a palavra "$palavra" é traduzida como  "$traducao".')
» texto = temp.substitute(lingua='português', palavra='intruder', traducao='intruso')
» print(texto)
↳ 'Em português a palavra "intruder" é traduzida como  "intruso".'

Bibliografia

Todas as URLs foram visitadas em janeiro de 2024.

Flet: Cores e Temas

Cores e Temas

É claro que uma escolha adequada de cores para o seu aplicativo é um passo essencial para a produção de um produto agradável de se olhar e usar. Essa escolha faz parte dos esforços de construir apps com boa usabilidade. O estudo completo de usabilidade e uso de cores é complexo. Algumas referências podem ser encontradas na bibliografia.

O Flet apresenta uma proposta de construção de interfaces gráficas que, por definição, devem ter boa aparência. Para isso podemos aplicar cores, transparências e sombreados aos controles.

Valores de Cores

Cores no Flet podem ser definidas por seu valor hexadecimal ou valores nomeados, idênticos aos usados com HTML e CSS. Em formato hexadecimal a cor é expressa por uma string com o seguinte formato:

Hexadecimal: #aarrggbb (0xaarrggbb) or #rrggbb (0xeeggbb).

Nesse código as letras significam: a opacidade, r vermelho, g verde, b azul; todas em notação hexadecimal.

Se o número de opacidade é omitido ele é ajustado para o valor máximo ff (255, totalmente opaco).

c1 = ft.Container(bgcolor='#ff0000')    # container de fundo vermelho
c2 = ft.Container(bgcolor='#00ff00')    # container de fundo verde
c3 = ft.Container(bgcolor='#0000ff')    # container de fundo azul

c4 = ft.Container(bgcolor='#80ff0000')  # fundo vermelho, 50% transparente

Valores nomeados: são strings que representam as cores e podem ser interpretadas pelos controles do Flet. Alternativamente elas podem ser passadas como propriedades do módulo flet.colors.

c5 = ft.Container(bgcolor=ft.colors.BLUE)
c6 = ft.Container(bgcolor='blue')

Opacidade: A opacidade (o inverso de transparência) pode ser ajustada com o método with_opacity, com valor entre 0.0 (100% transparente) e 1.0 (0% transparente).

color = ft.colors.with_opacity(0.5, ft.colors.PRIMARY)
color = ft.colors.with_opacity(0.5, '#ff6666')
color = ft.colors.with_opacity(0.5, '#ff6666')
color = "#80fff6666"
color = "blue, 0.5" #  50% azul

Cores de Tema

Esse esquema é baseado no ColorScheme do Flutter que, por sua vêz é baseado nas especificações do Material Design.

Material Design é uma linguagem de design desenvolvida pelo Google e apresentada em 2014. Ele layouts baseados em grade, animações e transições responsivas, e profundidade efeitos de iluminação e sombras. Seu principal objetivo é o estabelecimento de uma linguagem visual combinando princípios de bom design com inovação técnica e científica.

Existem 30 cores de temas nomeadas em theme.color_scheme que são geradas de acordo com a semente (seed) pela propriedade color_scheme_seed, sendo o azul a cor de seed default.

Figura 1: Cores em ft.colors. Por exemplo: ft.colors.INDIGO_ACCENT_200

Cores dos controles

Muitos controles do Flet recebem cores default que dependem do tema escolhido (color_scheme), que define as cores de todos os controles em todos os níveis do aplicativo. Essas cores podem ser sobrescritas em diversos níveis, tais como atribuindo a cor de fundo ou destaque (background e foreground) de um container ou botão, personalizando os componentes de uma barra de rolagem (scrollbar) ou de guias (tabs).

Cores locais nos controles
Para definir a cor local (“control level”) de um controle específico, usamos:

ctl = ft.Container(width=100, height=70, bgcolor=ft.colors.BLUE_400)
bt = ft.ElevatedButton("Go", icon="arrow_circle_left", bgcolor="white", width=150, height=30)
ctl2 = ft.Container(width=50, height=50,
                    border=ft.border.all(1, "#293B4A"),
                    border_radius=ft.border_radius.all(10),
                    bgcolor="#F1EBC5")

Cores dos controles com temas
Alguns controles não podem ter sua cor ajustada localmente e suas cores são definidas apenas pelo tema. É o caso de FilledButton cuja cor default primária (“primary” color) é definida pelo tema de seu controle pai (seu conteiner).

Para os controles sem definição de cores locais, como a barra de rolagem (ScrollBar), suas cores serão obtidas a partir de seu ancestral mais próximo, se eles possuem a definição de tema para essas barras. Isso também ocorre com Tabs ou Text.
Nota: ScrollBars são (usadas nos controles Page, View, Column, Row, ListView and GridView, Tabs e Text. Para personalizar um controle específico (ScrollBar, Text ou Tabs control) podemos envolvê-lo em um container e personalizar o tema respectivo (scrollbar_theme, text_theme ou tabs_theme) no tema desse container.

Níveis de temas
O Flet procura o tema definido na antecessor mais próximo, usando aquele ColorScheme. Por exemplo, o código abaixo define um FilledButton dentro de um Container, que é seu antecessor mais próximo. A cor primária do botão será obtida no tema do Container. Por exemplo, o código:

import flet as ft

def main(page: ft.Page):
    container = ft.Container(
        width=200,
        height=200,
        bgcolor="#E3DA2D",
        border=ft.border.all(5, ft.colors.INDIGO_ACCENT_200), 
        content=ft.FilledButton("Cor Primária\n(Primary color)"),
        theme=ft.Theme(color_scheme=ft.ColorScheme(primary=ft.colors.DEEP_PURPLE_100)))

    page.add(container)

ft.app(target=main)
Figura 2: resultado do código

Esse código gera a imagem na figura 2.
Caso a propriedade de cor não esteja definida localmente no controle ou por tema, nem no antecessor mais próximo, a cor será buscada no próximo antecessor disponível, que pode ser a página (page) com seu color_scheme definido (ou default).

Tema nas páginas

Temas são atribuídos às páginas (page) através da propriedade page.theme, que recebe uma instância da classe theme.Theme. No presente estado de desenvolvimento do Flet um tema só pode ser gerado automaticamente por meio de uma cor semente (seed). Por exemplo, para gerar um tema claro baseado na cor verde usamos:

page.theme = theme.Theme(color_scheme_seed="green")
page.update()
Figura 3: tema default e com seed

A figura mostra a renderização da interface com o mesmo código do exemplo na figura anterior, destituído de cores. Os objetos assumeme suas cores com o tema default. A imagem à direita mostra o efeito de page.theme = theme.Theme(color_scheme_seed=”green”).

Além disso a classe Theme possui outras propriedades:

Propriedade Descrição
color_scheme_seed cor usada pelo algoritmo para construir as demais cores do tema.
color_scheme instância da classe ft.ColorScheme para customização do esquema de cores derivado de color_scheme_seed.
text_theme instância da classe ft.TextTheme para customização de estilos de texto contrastando com as cores de card e canvas.
primary_text_theme instância da classe ft.TextTheme que descreve tema para textos em contraste com as cores primárias.
scrollbar_theme instância da classe ft.ScrollbarTheme para customização da aparência de scrollbars.
tabs_theme instância da classe ft.TabsTheme para customização da aparência de Tabs.
font_family a fonte base para todos os elementos gráficos.
use_material3 booleano (default=True) para usar design do Material 3 design. Caso contrário usa Material 2.
visual_density enun ThemeVisualDensity: STANDARD (default), COMPACT, COMFORTABLE, ADAPTIVE_PLATFORM_DENSITY.
page_transitions instância de PageTransitionsTheme para customização de transições de navegação na página para diferente plataformas. Veja a seção sobre transições.

ColorScheme
A classe ColorScheme tem propriedades como:

  • primary: cor primária de telas e componentes
  • secondary: cor de destaque usada em componentes menos proeminentes na interface
  • error: cor usada para validação de campos de entrada, como TextField e error_text
  • background: cor de fundo de conteúdos roláveis (com scroll)
  • shadow: cor das sombras sobre componentes elevados
Figura 4: Propriedades de ColorScheme

Uma lista completa das propriedades pode ser vista abaixo.



Classe TextTheme
É usada para a customização de estilos de texto. TextTheme tem as seguintes propriedades de ft.TextStyle:

Propriedade Descrição
body_large estilo de texto grande usados em passagens longas.
body_medium estilo de texto médio (junto com body_large). É o default da padronização Material.
body_small estilo de texto pequeno.
display_large estilo para o maior texto, reservado para trechos curtos e importantes. Melhor em telas grandes.
display_medium estilo de tamanho médio.
display_small estilo de tamanho pequeno.
headline_large estilo para cabeçalhos grandes. Cabeçalhos (headlines) são menores que display. Adequado para texto curto e telas menores.
headline_medium estilo para cabeçalhos (headlines) medios.
headline_small estilo para cabeçalhos (headlines) pequenos.
label_large estilo para labels grandes. Labels são menores e usados para texto dentro de componentes, como legendas. Úteis em ElevatedButton, TextButton e OutlinedButton.
label_medium Tamanho médio em estilo de labels.
label_small Tamanho pequeno em estilo de labels.
title_large estilo para títulos grandes. Títulos são menores que headlines e devem ser usados para textos curtos de ênfase média.
title_medium estilo para títulos médios.
title_small estilo para títulos pequenos.

Classe ScrollbarTheme
Customiza as cores, espessura e forma de barras de rolagem scrollbars em todo o aplicativo.

A classe ScrollbarTheme tem as seguintes propriedades:

thumb_visibility visibilidade da alça (thumb) da barra de rolagem (scrollbar) mesmo quando não em uso. Se False a scrollbar será exibida apenas quando em uso. A propriedade pode ser um valor booleano ou um dicionário tendo como chaves as propriedades de ft.MaterialState e os valores booleanos.
thickness largura da scrollbar no eixo de rolagem. Pode ser um valor de ponto flutuante ou um dicionário tendo como chaves as propriedades de ft.MaterialState e números como valores.
track_visibility Se o trilho (track) scrollbar deve ser visível. Se True o trilho permanecerá visível enquanto sua alça estiver visível. Se a alça não for visível o trilho também não será. Se a propriedade for ajustada para None essa visibilidade será False e o tema ScrollbarTheme.track_visibility do Theme.scrollbar_theme será usado. O valor default é False se esse último também for None. Essa propriedade também pode ser um booleano ou um dicionário tendo como chaves as propriedades de ft.MaterialState e números como valores.
radius o raio de arredondamento da alça da barra de rolamento.
thumb_color sobrescreve a cor default do Scrollbar thumb. Esse valor pode ser uma cor ou um dicionário de ft.MaterialState.
track_color sobrescreve a cor default do scrollbar track. Esse valor pode ser uma cor ou um dicionário de ft.MaterialState.
track_border_color sobrescreve a cor default da borda da alça. Esse valor pode ser uma cor ou um dicionário de ft.MaterialState.
cross_axis_margin distância entre a alça da barra até a borda mais próxima. A barra de rolamento preenche todo esse espaço. O valor não pode ser none e tem default 0.
main_axis_margin distância entre o início da alça da barra até a borda da caixa onde ele está desenhado. Esse valor afeta a área disponível para a barra. A barra de rolamento preenche todo esse espaço. O valor não pode ser Null e tem defaul 0.
min_thumb_length valor mínimo preferencial para o comprimento da alça da barra quando o comprimento da barra é muito grande.
interactive booleano, se True a barra de rolagem será interativa, repondendo ao arrasto da alça ou clique (ou toque) no trilho. Se False a barra não responderá a eventos de gestos ou hover, mas permitira cliques em toda a sua extensão. Defaults é True se valor = None (exceto no Android onde o default é False.
Figura 6: Tabs (abas ou guias)
Figura 5: Terminologia em Scrollbar

Aqui usamos a terminologia:
scrollbar: barra de rolagem
track: trilho
thumb: alça

tabs: abas ou guias

Classe TabsTheme
Customiza a aparência dos controles de Tabs em todo o aplicativo.

A classe TabsTheme tem as seguintes propriedades:

divider_color cor do divider.
indicator_border_radius raio das bordas do indicador.
indicator_border_side cor and peso (weight) da linha horizontal abaixo do tab selecionado.
indicator_padding indica localização do sublinhado sob o tab selecionado em relação à sua borda. A propriedade indicator_tab_size é marcada como False para definir o indicador centralizado e como True para todo o tab.
indicator_color cor da linha abaixo do tab selecionado.
indicator_tab_size se True o indicador ocupa todo o tab.
label_color cor dos rótulos labels dos tabs selecionados.
unselected_label_color cor dos rótulos labels dos tabs não selecionados.
overlay_color define a resposta de “tinta” sob ação de focus, hover e splash.

Transições de Navegação
theme.page_transitions permite a costumização dos efeitos de transição da página. Esses efeitos são diferentes para as diversas plataformas. Seu valor é uma instância da classe PageTransitionsTheme com as seguintes propriedades opcionais:

  • android (default: FADE_UPWARDS)
  • ios (default: CUPERTINO)
  • macos (default: ZOOM)
  • linux (default: ZOOM)
  • windows (default: ZOOM)

As transições admitidas estão no enum ft.PageTransitionTheme:

  • NONE, nenhum delay, transição sem animação,
  • FADE_UPWARDS, desaparece de baixo para cima,
  • OPEN_UPWARDS, abre de baixo para cima,
  • ZOOM, ampliação
  • CUPERTINO, abre no estilo Cupertino.

Segue um exemplo:

theme = ft.Theme()
theme.page_transitions.android = ft.PageTransitionTheme.OPEN_UPWARDS
theme.page_transitions.ios = ft.PageTransitionTheme.CUPERTINO
theme.page_transitions.macos = ft.PageTransitionTheme.FADE_UPWARDS
theme.page_transitions.linux = ft.PageTransitionTheme.ZOOM
theme.page_transitions.windows = ft.PageTransitionTheme.NONE
page.theme = theme
page.update()

Tema de Página
A propriedade page.theme admite como valor opcional o enum ThemeMode com valores:
SYSTEM (default), LIGHT ou DARK.

Bibliografia

Todas as URLs foram visitadas em janeiro de 2024.

Flet: Stack

Objeto Stack

Em alguns casos queremos colocar controles em cima de outros. No Flet é possível sobrepor vários filhos do controle Stack. Podemos, por exemplo, colocar um texto sobre uma imagem ou um container móvel, como fizemos no exemplo 3.

Propriedades de Stack

O controle Stack possui apenas 2 propriedades:

clip_behavior
Como será cortado (clipped) o conteúdo do objeto.
Os valores possíveis estão armazenados em no enum ClipBehavior com os valores:

  • NONE
  • ANTI_ALIAS
  • ANTI_ALIAS_WITH_SAVE_LAYER
  • HARD_EDGE (default)

controls
Uma lista contendo os controles a serem exibidos dentro de Stack, em ordem de exibição, sendo o último controle exibido por cima dos demais.

Controles dentro de Stack

Diversos controles, ao serem colocados dentro de um Stack passam a admitir propriedades de posição. São elas:

Figura 1: distâncias em Stack

left: distância entre a borda esquerda do controle filho até a borda esquerda do Stack.
right: distância entre a borda direita do controle filho até a borda direita do Stack.
bottom: distância entre a borda inferior do controle filho até a borda inferior do Stack.
top: distância entre a borda superior do controle filho até a borda superior do Stack.

Exemplo de uso do Stack

O exemplo de código a seguir insere 3 controles dentro de um Stack, 1 imagem e 2 linhas. Nessa posição eles admitem as propriedades listadas acima, em particular top e left que são usadas para mover a linha de texto.

1  import flet as ft
2  import time
3  
4  def main(page: ft.Page):
5      def voltar(e):
6          texto.size = 50
7          linha_texto.top=500
8          linha_texto.left=0
9          page.update()
10 
11     def partir(e):
12         while linha_texto.top > 0:
13             time.sleep(.1)
14             texto.size -= 1
15             linha_texto.top-=10
16             linha_texto.left+=10
17             page.update()
18 
19     imagem = ft.Image(src=f"https://phylos.net/wp-content/uploads/2020/02/deepfield.jpg",
20                       width=950, height=556, fit=ft.ImageFit.NONE)
21    
22     texto = ft.Text("Em uma galáxia muito muito distante...",
23                      color="yellow", size=50, weight="bold", opacity=0.3)
24   
25     linha_texto = ft.Row([texto], left = 0, top=500)
26
27     bt_partir = ft.ElevatedButton("Partir!", bgcolor="blue", color="white",
28                                   width=120, height= 35, on_click=partir)
29
30     bt_voltar = ft.ElevatedButton("Voltar", bgcolor="blue", color="white",
31                                    width=120, height= 35, on_click=voltar)
32
33     linha_botoes = ft.Row([bt_partir,bt_voltar], left = 10, top=10)
34
35     page.add(ft.Stack([imagem, linha_texto,linha_botoes], width=950, height=556))
36 
37 ft.app(target=main)
Figura 2: resultado do código com Stack. Apenas 3 frames são mostrados.

Um clique no botão Voltar retorna as propriedades do texto e da linha que o contém para seus valores iniciais. Observe que, se o botão Partir! for acionado antes que o loop na linha 12 tenha terminado a velocidade de subida do texto aumentará pois os incrementos serão aumentados (loops dentro de loops).

Exemplo: sobreposição de controles

Mais um exemplo ajudará a mostrar que, dentro de um Stack, controles desenhados estão dispostos em camadas. Se dois controles são posicionados no mesmo lugar o último deles, na camada superior, ficará visível, cobrindo o controle por baixo.

1  import flet as ft
2  
3  class Ct(ft.Container):
4      def __init__(self, cor, acima, direita, abaixo, esquerda):
5          super().__init__()
6          self.width=20
7          self.height=20
8          self.border_radius=5
9          self.bgcolor=cor
10         self.top=acima
11         self.right=direita
12         self.bottom=abaixo
13         self.left=esquerda
14   
15 def main(page: ft.Page):
16     page.horizontal_alignment = ft.CrossAxisAlignment.CENTER
17     page.vertical_alignment = ft.MainAxisAlignment.CENTER
18
19     def mover(e):
20         e.control.data = (e.control.data % 5) + 1
21         i = e.control.data
22         st.controls.pop()
23         if i==1: ct5=Ct("purple", 0, 60,60,0)
24         elif i==2: ct5=Ct("purple", 0,0,60,60)
25         elif i==3: ct5=Ct("purple", 60,0,0,60)
26         elif i==4: ct5=Ct("purple", 60,60,0,0)
27         else: ct5=Ct("purple", 30,30,30,30)
28         st.controls.append(ct5)
29         st.update()
30
31     ct1 = Ct("red", 0, 60,60,0)
32     ct2 = Ct("yellow", 0,0,60,60)
33     ct3 = Ct("blue", 60,0,0,60)
34     ct4 = Ct("green", 60,60,0,0)
35     ct5 = Ct("purple", 30,30,30,30)
36     ct5.data=0
37     bt_mover = ft.ElevatedButton("Mover", bgcolor="blue", color="white",
38                                   width=120, height= 35, data = 0, on_click=mover)
39
40     st = ft.Stack([ct1, ct2, ct3,ct4, ct5])
41     st.data = 0
42
43     page.add(ft.Container(st, border_radius=8, padding=5,
44                           width=100, height=100, bgcolor="black"), bt_mover)
45
46 ft.app(target=main)
Figura 3: sobreposição de controles com Stack.

O exemplo também ajuda a ilustrar o uso de POO no Flet. Como muitos controles com propriedades semelhantes serão criados, a classe Ct foi criado na linha 3, herdando de um ft.Container. Objetos criados nas linhas 31 a 35 passam para o construtor apenas a cor e a posição do container.

A função mover(), acionada por bt_mover remove o último objeto no Stack na linha 22 e cria um novo container roxo por cima dos demais, circularmente. O container coberto não deixa de existir e reaparece na próxima operação.

Flet: Exemplo 3

Captura de toques de teclado

Atalhos de Teclado

Na seção Widgets: Atalhos de Teclado vimos como capturar a interação do usuário com o aplicativo através de eventos de teclados. A captura de eventos produzidos pelo teclado se dá através do evento page.on_keyboard_event, que gerencia o pressionamento de teclas de letras em combinação com teclas de controle. Esse evento passa o parâmetro e que é uma instância da classe KeyboardEvent, e tem as seguintes propriedades:

e.key Representação textual da tecla pressionada.
e.shift Booleano: True se a tecla “Shift” foi pressionada.
e.ctrl Booleano: True se a tecla “Control” foi pressionada.
e.alt Booleano: True se a tecla “Alt” foi pressionada.
e.meta Booleano: True se a tecla “Meta” foi pressionada††.

Desta forma conseguimos capturar o pressionamento de uma única letra, além de Enter, Backspace, F1F12, Escape, Insert, Page Down, Pause, etc, ou de combinações como Ctrl-F ou Ctrl-Shift-Enter.

Como exemplo adicional vamos exibir o código de um jogo que captura a interação com o teclado. Uma combinação de teclas como Ctrl-H ou SHIFT-L é exibida em um container que desce do topo da página. Se o usuário digita a mesma combinação ele pontua (10 pontos de cada vez) e nova combinação é exibida.

1   import flet as ft
2   import time, random, string
3
4   cores = ["#FFC6C6", "#A8DCEA", "#BAF3E4", "#F1E9AF",
5            "#CBB1CE", "#B2C9F3", "#F0DCBE", "#F1D7B3"]
6
7   def main(page: ft.Page):
8       def sortear():
9           ct.top = 10        
10          ct.left = random.randrange(100, 1000)
11          ct.height=80
12          t1 = ["Shift", "Alt", "Ctrl"][random.randrange(0, 3)]
13          t2 = random.choice(string.ascii_letters).upper()
14          ct.content = ft.Text(f"{t1}-{t2}", size=20)
15          ct.bgcolor = cores[random.randrange(0, 8)]
16          ct.visible = True
17
18      def fim(e):
19          page.window_destroy()
20
21      def inicio(e):
22          while True:
23              sortear()
24              while ct.top < 400:
25                  time.sleep(.3)
26                  ct.top += 10
27                  page.update()
28              inicio(e)
29
30      def teclou(e):
31          txt = "Shift" if e.shift else "Alt" if e.alt else "Ctrl" if e.ctrl else ""
32          txt = f"{txt}-{e.key}"
33
34          if ct.content.value == txt:
35              pts = int(txtPontos.value.split(":")[1]) + 10
36              txtPontos.value = f"Sua pontuação: {str(pts)}"
37              ct.bgcolor = "red"
38              while ct.top < 400:
39                  time.sleep(.01)
40                  ct.top += 10
41                  ct.height -= 3
42                  page.update()
43
44      ct = ft.Container(padding = 15, width=180, alignment = ft.alignment.center,
45                        border = ft.border.all(2, "black"),
46                        border_radius = ft.border_radius.all(15),
47                        blur=90, visible = False)
48
49      btInicio = ft.ElevatedButton("Começar Jogo", bgcolor="white",
50                                  width=180, height= 40, on_click=inicio)
51      btFim = ft.ElevatedButton("Terminar Jogo", bgcolor="white",
52                                width=180, height= 40, on_click=fim)
53      txtPontos = ft.Text("Sua pontuação: 0", size=27, weight=ft.FontWeight.BOLD)
54      lin = ft.Text("Acerte a combinação de teclas mostrada na tela (Ctrl, Shift, Alt) + Letra",
55                    size=27)
56      linha1 = ft.Row([lin], alignment=ft.MainAxisAlignment.SPACE_EVENLY)
57      linha2 = ft.Row([btInicio, txtPontos, btFim],
58                      alignment=ft.MainAxisAlignment.SPACE_EVENLY)
59
60    page.add(linha1, linha2, ft.Stack([ct]))
61    page.on_keyboard_event = teclou
62
63  ft.app(target=main)

Nesse bloco de código usamos a notação Camel case para dar nomes às variáveis. Ela consiste em usar a primeira letra minúscula e a primeira letra de cada nova palavra subsequente maiúscula. Como exemplo temos casaDaVovo ou notaAluno. O desenvolvedor pode escolher que tipo de notação usar, sendo consistente em seu código e procurando respeitar as convenções da linguagem.

O início do jogo ocorre quando se clica o botão btInicio que dispara a função inicio(). Dentro dela um loop infinito promove várias interações do container descendo a tela (o que é obtido com container.top += 10). Quando o container chega em seu valor máximo estabelecido, no caso ct.top < 400, novos valores são sorteados como suas propriedades e o container e redesenhado no topo.

O sorteio define a posição (top) inicial, uma cor aleatória escolhida dentro de uma lista de cores (linha 15) e monta uma string para representar uma combinação de teclado (linhas 12 a 14). A linha 13 usa random.choice() para escolher aleatoriamente um dos caracteres de string.ascii_letters, e torná-lo maísculo. Esse carater é juntando à um controle. A tecla de controle Meta (Windows) não foi usada pois é comum que ela esteja associada a atalhos globais do computador, em algumas instalações.

A interação do usuário é capturada em teclou que compara a combinação sorteada com aquela teclada pelo usuário. Se ocorreu um acerto ela incrementa a pontuação, derruba o container (acelerando sua queda) e sorteia nova combinação. O loop infinito iniciado na linha 22 só é terminado com o evento btFim.on_click.

Captura de teclas no Python

Claro que podemos capturar o pressionamento de tecla no Python, sem usar os métodos do Flet. Para isso podemos instalar, entre outras escolhas, o módulo keyboard, que funciona em sistemas operacionais Windows e Linux.

# Instale o módulo de teclado usando PIP:
pip install keyboard

# No Python 3 instale usando o comando:
pip3 install keyboard

Para detectar pressionamentos de teclas podemos usar a função is_pressed(). Esse método recebe um caractere como entrada e retorna True se essa tecla foi pressionada. O exemplo seguinte usa um loop que só é terminado com o pressionamento da tecla f.

import keyboard

print("Pressione 'f' para terminar.")
while True:
    if keyboard.is_pressed("a"):
        print("A tecla 'f' foi pressionada!")
        break

A função keyboard.is_pressed("f") retorna False se qualquer outra tecla fopr pressionada.

Também podemos usar a função read_key() para capturar pressionamentos de teclas. Essa função retorna a tecla pressionada pelo usuário.

import keyboard
while True:
    print(keyboard.read_key())
    if keyboard.read_key() == "f":
        print("Você terminou o loop pressionando 'f'.")
        break

Esse código exibe na tela todas as teclas pressionadas até que se tecle “f”.

Outra forma de captura de pressionamento de teclas usa a função wait(), que recebe um caractere como entrada. Quando executado o programa é pausado até que seja pressionada a tecla passada como argumento para a função.

import keyboard
keyboard.wait("f")
print("Você digitou 'f'.")

Nesse último exemplo fica dispensado o uso de um loop para suspender a execução do código.

Bibiografia

Flet: Exemplo 2


Exemplos 2: Referências a controles

Variáveis são referências

Widgets são classes comuns do Python, com suas propriedades e métodos. Para atuar sobre os objetos criados fazemos uma referência a eles, por meio dos nomes de variáveis. Vale lembrar que no Python toda variável é uma refeerência a algum objeto. Por exemplo, no código abaixo, um objeto flet.Text foi atribuído à variável t.

1   import flet as ft
2   
3   def main(page: ft.Page):
4   
5       def mudar_texto(e):
6           t.value="Um texto em azul!"
7           t.color="blue"
8           page.update()
9   
10      t = ft.Text(value="Um texto em vermelho!", color="red", size=20)
11      bt=ft.ElevatedButton("Mudar texto", on_click=mudar_texto)
12      page.add(t,bt)
13
14   ft.app(target=main)
Figura 1

A linha 10 contém o código de inicialização do objeto Text onde atribuimos valor a duas propriedades, respectivamente value (o texto que será exibido) e color (a cor da fonte usada). Com um clique no botão bt as propriedades t.value e t.color são alteradas, usando a variável como referência ao objeto. A figura 1 mostra o estado inical do aplicativo, com o texto em vermelho, e após o clique no botão Mudar texto.

Obs.: para exibir t e bt na mesma linha podemos inserir uma linha na página contendo os dois widgets: page.add(ft.Row([t,bt])). Nesse caso o controle Row (em flet.Row(<lista-de-controles>))) serve de container para os controles na lista <lista-de-controles>.

Relembrando: t é uma referência à uma instância da classe Text.

Vimos que page recebe uma lista (de controles) no parâmetro controls. Essa lista pode ser tratada como qualquer outra lista do Python. Por exemplo, ela possui o método pop(n).

1   for i in range(6):
2       page.controls.append(ft.Text(f"Exibindo a linha {i}"))
3       page.update()
4
5   page.controls.pop()
6   page.update()
Figura 2

Esse código insere e exibe 6 linhas de texto na página. Em seguida ela exclui a última linha com page.controls.pop(). Assim com o fazemos com outras listas, page.controls.pop(n) excluiria a n-ésima linha.

A figura 2 mostra as 5 linhas restantes após a ação de page.controls.pop().

Referências para controles com a Classe Ref

Outro exemplo explora a mesma possibilidade manipulação das variáveis como referências aos objetos de controle. Os objetos TextField são criados com seus textos vazios, preenchidos pelo usuário, usados para inserir a linha 9de cumprimento com o clique do botão. O comando page.update() atualiza na tela apenas as campos que foram alterados. A propriedade autofocus=True na linha 4 garante que o cursor voltará para o objeto nome após a execução da função fala_oi.

1   import flet as ft
2
3   def main(page):
4       nome = ft.TextField(label="Nome", autofocus=True)
5       sobrenome = ft.TextField(label="Sobrenome")
6       coluna_ola = ft.Column()
7   
8       def fala_oi(e):
9           coluna_ola.controls.append(ft.Text(f"Olá, {nome.value} {sobrenome.value}!"))
10          nome.value = ""
11          sobrenome.value = ""
12          page.update()
13          nome.focus()
14    
15      page.add(
16          nome,
17          sobrenome,
18          ft.ElevatedButton("Diga oi!", on_click=fala_oi),
19          coluna_ola,
20      )
21
22  ft.app(target=main)

Em códigos mais longos e complexos um número maior de controles é adicionado, juntamente com suas propriedades e funções que manipulam seus eventos. Fica cada vez mais difícil, para o programador, se lembrar de todas as definições de nomes, por mais organizado que ele seja. A inserção de controles na página, efetuada nas linhas 15 a 20 não deixa muito clara a estrutura de controles inseridos.

Todos os controles do Flet possuem a propriedade ref. De acordo com os propgramadores do Flet esse é um conceito inspirado no React.

Para isso o Flet incluiu uma classe utilitária chamada Ref, usada para fazer uma referência a um controle que pode ser usada em gerenciadores de eventos (event handlers) e, posteriormente, ser conectada a um controle real quando se constroi a árvore do aplicativo.

Para demontrar o uso dessa classe vamos alterar o código do exemplo acima usando Refs. Listamos abaixo como definir uma nova referência, como usar essa referência para inserir valores e, finalmente, como atribuir um controle real a essa referência, aproveitando todas as suas propriedades já definidas.

1   # criar uma referência a um TextField (por exemplo)    
2   nome = ft.Ref[ft.TextField]()
3   
4   # acessar o controle referenciado
5   nome.current.value = "José Ninguém"
6   
7   # atribuindo a referência um controle real, que pode ser incluído na página
8   page.add(
9       ft.TextField(ref=nome, label="Nome", autofocus=True)
10   )

Vemos que objetos da classe Ref possuem a propriedade current que, por sua vez, contém as mesmas propriedades e métodos do pbjeto referenciado. Para ligar essa referência a um controle utilizamos a propriedade Control.ref do controle. Com essas definições a aplicativo pode ser escrito como:

1   import flet as ft
2   
3   def main(page):
4       nome = ft.Ref[ft.TextField]()
5       sobrenome = ft.Ref[ft.TextField]()
6       coluna_ola = ft.Ref[ft.Column]()
7   
8       def fala_oi(e):
9           coluna_ola.current.controls.append(
10              ft.Text(f"Olá, {nome.current.value} {sobrenome.current.value}!")
11          )
12          nome.current.value = ""
13          sobrenome.current.value = ""
14          page.update()
15          nome.current.focus()
16   
17      page.add(
18          ft.TextField(ref=nome, label="Nome", autofocus=True),
19          ft.TextField(ref=sobrenome, label="Sobrenome"),
20          ft.ElevatedButton("Diga oi!", on_click=fala_oi),
21          ft.Column(ref=coluna_ola),
22      )
23
24  ft.app(target=main)
Figura 3

Observe que, fazendo isso, a estrutura da árvore de controles se torna mais claramente visível quando os controles são adicionados à página, na linha 17 e seguintes.

A figura 3 mostra os campos preenchidos e o resultado do clique no botão Diga oi.

Interação com o usuário

Claro que a maioria dos aplicativos demandam algum tipo de interação com o usuário, seja para escolher um ítem de busca, inserir novos dados ou escolher entre opções. Os exemplos acima usam de flet.TextField para a inserção de textos e ft.ElevatedButton para receber cliques e acionar uma função. Claro que existem muitas outras formas de interação que podem ser simples como um clique em botão ou sofisticadas quanto capturar a posição na tela de um clique, dentro de algum objeto desenhado na página.

Caixas de checagens e “dropdowns”

Vimos vários exemplos de uso das caixas de texto puro flet.Text(“Texto a exibir!”), usadas para exibir texto, e caixas interativas flet.TextField onde o usuário pode digitar dados e inserí-los no aplicativo.

As caixas de checagem, flet.Checkbox são úteis quando a escolha de dados é binária, geralmente sim/não.

1   import flet as ft
2   
3   def main(page):
4       def checkbox_mudou(e):
5           texto_exibido.value = f"A caixa de checagem está  {'marcada' if check.value else 'desmarcada'}."
6           page.update()
7
8       texto_exibido = ft.Text()
9       check = ft.Checkbox(label="Clique na caixa de checagem...", value=False, on_change=checkbox_mudou)
10      page.add(check, texto_exibido)
11   
12  ft.app(target=main)
Figura 4

Esse código produz o resultado mostrado na figura, dependendo da caixa estar marcada ou não. O evento capturado nesse caso foi o flet.Checkbox.on_change que envia o evento para a função selecionada. Na função é lida a propriedade booleana check.value. A figura 4 mostra os dois estados possíveis do aplicativo.

Foi usado o operador trinário valor_se_verdadeiro if condição else valor_se_falso.

Dropdowns, flet.Dropdown são úteis quando várias escolhas de dados estão disponíveis. O conjunto permitido de escolhas pode ser inserido durante o desenvolvimento ou alterado pelo usuário.

1   import flet as ft
2
3   def main(page: ft.Page):
4       def dropdown_mudou(e):
5           escolhido.value = f"Você afirmou que prefere {dpd_linguagem.value}"
6           page.update()
7   
8       escolhido = ft.Text()
9       itens_escolher = [
10               ft.dropdown.Option("Python"),
11               ft.dropdown.Option("Java"),
12               ft.dropdown.Option("Javascript"),
13               ft.dropdown.Option("C, C+"),
14               ft.dropdown.Option("Rust"),
15               ft.dropdown.Option("Ruby"),
16               ]
17       dpd_linguagem = ft.Dropdown(
18           label="Linguagem de programação",
19           width=100,
20           options=itens_escolher,
21           on_change=dropdown_mudou,
22       )
23       page.add(dpd_linguagem, escolhido)
24   
25   ft.app(target=main)
Figura 5

Observe que flet.Dropdown.options é uma lista de objetos dropdown.Option(“nome”). O resultado está mostrado na figura 5.

Além do evento change, as caixas dropdown também podem responder a eventos on_blur, disparado quando o controle perde o foco, e on_focus, quando o controle recebe o foco.

Os ítens na caixa de seleção podem ser inseridos ou apagados dinamicamente, em tempo de execução, como mostramos no código seguinte.

1   import flet as ft
2   
3   def main(page: ft.Page):
4       def inserir(e):
5           if txt_insere.value:
6               dp_box.options.append(ft.dropdown.Option(txt_insere.value))
7               dp_box.value, txt_insere.value = txt_insere.value, ""
8               page.update()
9
10      def apagar(e):
11          for item in dp_box.options:
12              if item.key == dp_box.value:
13                  dp_box.options.remove(item)
14          page.update()
15
16      dp_box = ft.Dropdown(width=600)
17      txt_insere = ft.TextField(hint_text="Nome a inserir")
18      bt_insere = ft.ElevatedButton("Inserir", on_click=inserir)
19      bt_apaga = ft.OutlinedButton("Apagar item exibido", on_click=apagar)
20      page.add(dp_box, ft.Row(controls=[txt_insere, bt_insere, bt_apaga]))
21   
22  ft.app(target=main)
Figura 6

Na linha 6 um item é inserido na caixa dropdown. dp_box.options é uma lista que pode ser acrescida de elementos com append. Essa lista é composta de objetos flet.dropdown.Option(texto). A operação de apagar procura por um item nessa lista e o remove, caso encontrado. A propriedade item.key extrai o texto de cada componente da lista. O texte feito na linha 12 é necessário porque tentar remover um item inexistente de uma lista resulta em erro. O aplicativo executado exibe algo como o representado na figura 6.

Capturando cliques e “hovers”

Um exemplo de captura da posição do cursor do mouse no momento do clique pode ser visto na página Layout do Flet: View e Container na seção Container: Eventos onde um clique dentro de um container dispara um evento para exibir as posições do ponto clicado, relativo ao container e à página.

No exemplo abaixo as ações são iniciadas pelo evento flet.Container.on_hover, disparadas quando o cursor do mouse entra ou sai da área delimitada pelo controle. O evento e passado para a função limpar carrega a propriedade e.data == "true" se o cursor entrou na área, e e.data == "false" se saiu dela. Na saída uma cor é escolhida eleatoriamente entre as cores do dicionário cores.

1   import flet as ft
2   import random
3
4   def main(page: ft.Page):
5       cores = {0:"#000000", 1:"#1D74FF", 2:"#C51709", 3:"#FFE000", 4:"#00CB4F",
6                5:"#A866DC", 6:"#FF6600", 7:"#aaffff", 8:"#145375", 9:"#a4b3c5"}
7
8       def limpar(e):
9           page.controls.pop()
10          page.add(matriz())
11          page.update()
12
13      def on_hover(e):
14          if e.data == "true":
15              e.control.bgcolor = "#efefef"
16          else:
17              e.control.bgcolor = cores[random.randrange(10)]
18          e.control.update()
19
20      def matriz():
21          matr = ft.Column()
22          for i in range(10):
23              lin = []
24              for j in range(10):
25                  lin.append(ft.Container(width=50, height=50,
25                             border=ft.border.all(1, "#293B4A"),
27                             border_radius=ft.border_radius.all(10),
28                             bgcolor="#F1EBC5", on_hover=on_hover)
29                  )
30              linha = ft.Row(lin)
31              matr.controls.append(linha)
32          return matr
33
34      tit=ft.Text("Passe o cursor sobre os quadrados", size=18, weight=ft.FontWeight.BOLD)
35      bt_limpar=ft.ElevatedButton("Limpar tudo", icon="arrow_circle_left",
36                bgcolor="white", width=150, height=30, on_click=limpar)
37      page.add(ft.Row([tit,bt_limpar]), matriz())
38
39  ft.app(target=main)

 

Figura 7

O resultado do código está representado na figura 7, após o cursor ter sido passado sobre o objeto matriz(), que é uma coluna.

A construção da matriz de controles container é feita através da função matriz() que retorna 10 linhas, cada uma com 10 containeres, todos respondendo à container.on_hover com a mesma função, que altera a cor de fundo desse objeto.

O laço iniciado na linha 24 constroi um array com 10 objetos Containers (os quadrados). Esse array é inserido em uma linha flet.Row na linha 30. Essas 10 linhas são inseridas na coluna matr na linha 31.

O botão Limpar tudo remove o último controle inserido na página com page.controls.pop(), sendo que esse controle é a matriz de quadrados coloridos. Em seguida ele repõe novos quadrados com as cores originais.

Q&A Religion – 01

About this

These are collected answers I wrote for sites on Questions and Answers, like Quora. I tried to remove duplicates but some may be left still.

Religion

Question: If Jesus’ existence is claimed to be a fact and so are his supposed miracles, why do atheists still choose not to believe in him?

Answer: You don’t need to believe in a thing you know. Beliefs come into play for those things you don’t know, most derived from revelations of a person or a book. I would say it is healthy to keep an open but skeptics mind.


Question: My religion teacher said that there are no atheists because in order to reject God, you must first have a concept of God, and if you have a concept of God, you are not an atheist. In what way is this true, if at all? Why?

Answer: I would agree in some extent. Atheism is a negative position. To that point I would say I am not EVEN an atheist, the same way you are not a-Thor or a-Shiva. Today, to claim you are an atheist is a position against religious ideias that have corrupted the minds for too long.

The ideal position is yet to come. People should not even care about the theistic world view. Absolutely the same way you would not bother to answer me if I claim I have captured a fairy which I keep in a box. You can’t see but you can feel it and be extremely happy if you just believe in it.


Question: If Jesus is the son of God, did God contribute his Y chromosome?

Answer: Wouldn’t it be better to find out if Jesus ever existed, before discussing his Y chromosome?


Question: My eight year old is studying Zen and has an idea related to the “one hand clapping” koan. He says that there really is no “no thing” — even at the edge of space there is the space itself. What do you think?

Answer: In my opinion the Zen strategy to shut up your mind may be beneficial to those who have worked hard their minds before. I’ve met people in zen who just know nothing and think nothing about everything.
Try making him interested in science, reading about biology, evolution, astronomy, and so on.


Question: How do atheists respond to the fine tuning argument?

Answer: It is a question with no clear cut answer, so far. But, different from what Craig Lane and others think, not knowing something is not a good reason to state the existence of a god. (actually it is a very poor argument).
There are some ideas been worked in physics, possible answers. One is the concept of multiverses (instead of one universe). If many universe, with different combination of fundamental constants exists, than we just happen to live in an appropriate universe.

There might also be arguments in the line of evolutionary biology (like, things evolved in the most beneficial way to develop diversity.


Question: If you could delete one and only one thing entirely from this world, what would that be and why?

Answer: Religion, the fear of death and the unknown.


Question: In a universe without God or immortality, how is mankind ultimately different from a swarm of mosquitoes or a barnyard of pigs?

Answer: Well, we share the DNA code, same origin, same life. Bu we have a more complex hardware for thinking and feeling. Most important of all, we humans have the ability to self inquiry, introspection, looking inside and asking why.
This same ability make us fear death, the unknown and because of this we invented a god (or gods).


Question: What is the easiest way to make an atheist believe in god(s)?

Answer: Maybe it is not possible. I would say “show him some evidence”. But, if you have evidence then there is no need for belief.

But there is another answer, more positive: wait until he/she gets really old and scared of death and his/her mental faculties begin to slow down. He/she might believe…


Question: If God exists, why can’t there be multiple gods? Polytheism was once a lot more popular, so if God might exist, why not more than one? And how would they differ from one big Daddy God?

Answer: I think human mind (and brain) is set to find the simplest explanation for all things. There are many colors but the theory shows they are variations of same vibrations of electromagnetic fields. There are many substances but they all are made of the same atoms. Think of the struggle to find an unified field theory for the 4 fields known.
God, and gods are a necessity of human brain (so far) and it would not break the pattern.


Question: In general, why do atheists tend to be hostile to people who believe in God(s), yet demand respect for their beliefs?

Answer: I agree that sometimes non religious people act rude towards religious ones. But I think this is a response because “people of faith” treats badly those who don’t share their beliefs (I mean BAD), specially atheists. Since this topic was never covered before (because there would be no proper place in public to argue against god) this fight may get harsh in near future.

Evangelicals, for instance, can’t see how offensive it is to claim they are the “people of god”, meaning that everyone else will go to hell.


Question: Why do some atheists spell “God” with a lower case, as “god” while writing about the Christian God when it is grammatically correct to capitalize it?

Answer: The bible says no one knows the name of god. So let us clarify: “god” is not a name but a noun. You have god or gods, the same as fairy and spirits. Christians capitalize god in respect to this concept. It IS NOT grammatically correct.


Question: How would you justify/answer the fact that everything came into ‘being’ by itself, without any creator? How did the laws of physics become what they are? Where do the principles of thought come from? Where do feelings come from?

Answer: The answers for these questions (in regard to physics) are not known. Maybe 42! But remember, ignorance is not a good excuse for belief.


Question: Aren’t agnostics the majority?

Answer: Hard to know. Many people, when asked or pooled about their faith, will just go with the larger group in his/her area. This is quite obvious in Brazil where, in doubt, you just say: I’m am a catholic.


Question: Why do atheists try to get agnostics to join their team?

Answer: I see your point. I think of myself as a not-even-atheist. Atheism is a denial of the existence of god or gods. One may as well choose not to discuss this thing. I did not invent the concept (absurd, in my opinion) of god – so I should not be called to decide about it.

It happens, in our times, that there is a fight going on and often you must say which side you favor. In this case I would call myself an atheist. Maybe you are best described as theist (I don’t know). But you DON’T have to take sides, if you don’t want to.


Question: Agnostics: Is it possible to know whether there’s a god?

Answer: I do not know about any god or gods. They may exist or not.
I haven’t seen any good hint they (or she/he) exist. So, why would I devote any of my time to such an improbable concept?


Question: Is the Quran the word of God? Are there any other texts that are the word of God? I heard Dr. Zakir Naik say a text has to pass the test of time in order to be treated as the word of God.

Answer: Can the Quran and the Bible and the Vedas and Bhagavad Gita and The Book of Mormon, and …, and …, be all true simultaneously?


Question: As a non-Muslim, did you read the Quran? What did you think?

Answer: Something doesn’t become true just because a lot of people believe it.
Actually, for most of human history, the majority of things people believes turned to be false. Have you read the bible? The Upanishds? Bhagavad Gita? The Tripitaka?


Question: When will Jesus come back?

Answer: It is said in the Bible that Jesus would be back very soon: “Verily I say unto you, This generation shall not pass, till all these things be fulfilled. ” Matthew:24:34. Isn’t it clear enough he will not come back? Actually if you realize he may not even have ever existed how to expect a “second” coming?


Question: I love both science and God, yet people expect me to take sides. Why can’t I choose both?

Answer: I had a similar dilemma… I don’t think you have to to take sides although I believe they are irreconcilable. The decision is hard to achieve so take as long as you need. Everyone is free to believe in whatever they want. They just should keep in mind that belief is not knowledge.


Question: What argument for the Abrahamic God’s existence do atheists consider the most persuasive?

Answer: None, with all due respect. The only argument I ever knew, as a child, was the fear we might be insulting god. Once you get rid of the fear, sincerely, none of these arguments make any sense. That is not the same as saying I know god doesn’t exist. All I know is that there is no compelling reason to bring such a concept into the debate.
I have friends, thought, who say they have a connection of some sort with something, be it the personal god of the bible or a type of Spinoza god. Who am I to say they are faking it or are deluded? (Even if I think they are!)


Question: Is the Abrahamic God responsible for all of the misery caused by natural disasters?

Answer: No, god is not responsible for that and not for anything else.


Question: If the universe is infinite with infinite planets with infinite possibilities, shouldn’t there be a planet with an actual theological god existing right now?

Answer: Yes, the universe may be (and looks like) infinite. But if god of the Bible exists there he would show up here as well (or he is not infinite and omnipresent). The very concept of god as depicted in the Bible is absurd.


Question: Would atheists agree that everyone believes in God, but it is just the definition of God that we all do not agree on?

Answer: Not at all. I am sure you would not agree with most definitions of “god” so it is not a good practice to change the meaning of the world to accommodate atheists.


Question: God made man in his image. Looking at the Earth today, could God possibly be behind the world’s outlook?

Answer: Sometimes even the question is wrong, making it impossible te answer it properly. Maybe it would be more reasonable to ask: “Supposing there is a god, did he make humans in his image?”

I would not have an answer for that either because it sounds to me very alike: “Aliens planted ebola virus on Earth. Should we be prepared for an invasion?”


Question: Are some theists pretending to believe in God, but deep down they know that God doesn’t exist?

Answer: What would you do if you spent your whole life as a priest (or pastor) depending on the church for your living, being not qualified for any real job, and suddenly finding out you don’t believe in god?


Question: To believe in God or not to believe in God?

Answer: Believe in whatever you want. Just don’t ever forget that believing is not the same as knowing. Believing in god will not cause it to exist, the same as not believing will not cause it to cease existence, in case it does exists.
I don’t believe in god and think there are no serious and compelling reason to care much about the subject. Also I think that people who believe strongly and run their lives (or try to) accordingly to the belief cause harm to themselves.


Question: How does Stephen Hawking prove that there is no god mathematically?

Answer: No one has a mathematical proof that god doesn’t exist. It is not necessary to prove this and it may be impossible to do so. You cannot prove the Invisible Pink Unicorn, or the tea pot around the sun are not real. The point is, can you or anyone else prove there is a god? If not it is just a belief and a tradition. Even if there is a god there is not enough evidence to place it nowhere close to a scientific hypothesis.


Question: What do Christians think happens to non-human animals after death?

Answer: Both the question and the available answers so far make it clear the very idea of a heaven for humans or animals doesn’t make sense. Humans are animals and there are no reason to believe they are so much better they deserve a special treatment when dead.
The evolutionary steps from an furry animal to present day humans are continuous and you can’t say there was a “first man or woman”. When would the soul come into these beings? So, paraphrasing Jack Daniels: ” let us enjoy ourselves while we are here and let us have a good time while alive”!


Question: What are the best quantum theories that support a life-after-death scenario?

Answer: The answer to this question is VERY simple. Quantum theory (not theories) does NOT support life after death. It’s got nothing to do with the subject of spirit, big foots, UFOs, fairies, ghosts … It doesn’t matter if you found a thousand books saying the opposite. We have, so far, no evidence of any link between the quantum theory and an explanation to consciousness (although it may be found, one day…!)
So, why so many authors insist on this sort of connection? First we, human beings, have an urgent need to find a way out of death. We hate the idea that we will be GONE one day. Second, quantum theory is hard to understand … consciousness is hard to understand too … so … voilá they must be related!


Question: Is there an atheist philosopher who is intellectually capable of arguing against William Lane Craig? Craig has done 20+ years of research in the two fields he debates, has published hundreds of academic books and papers on both subjects.

Answer: I guess it is difficult for a religious person to understand you can spend decades over the Bible or other books with religion contents … and it does not mean much. 20+ PHD level on nothing is nothing.
W. Lane talks in soft voice using elaborate words but with little content. Also he picks some points on physics and cosmology but does not show to really understand the epistemology or the inner guts working of science.
To his credit I would agree he is polite and always try to hold the debate on a high level. But just not a match for Richard Dawkings who does not want to debate him because he understands it would be a huge promotion for Lane and pretty much a waste of time for him.


Question: Why is it bad to be materialistic (in a scientific way)?

Answer: I would suggest that the concept of materialism is empty, just as matter itself is made of empty space and fields.


Question: In the materialistic world even spirituality is being treated as a commodity of information, the way it is publicized and marketed that, it is often felt that it can also be purchased at a price. Do you agree?

Answer: I think the word “spiritualism” has no meaning at all, just as we can assign no meaning to the root word “spirit”.
Maybe we can talk about the spirit as being the inner works of humans, their psique, mind, feelings, aspirations, fears … but then I suggest we should not use the word because of its aggregated meaning as “consciousness independent of the body”, something we can not prove to be true.


Question: Can atheists demonstrate without a reasonable doubt that the suffering in our world is meaningless?

Answer: The concept of “meaning for suffering” is purely a human construct, with no correspondence in nature.


Question: Why did eminent scientists like Newton, Einstein, Gauss have a strong belief in the existence of God?

Answer: Many of these scientists studied math and the universe in order to “reveal the glory of god”. That was the mental state in their times and very few people would even dare to think differently. Newton was a great example. He devoted most of his time to study the bible and alchemy. He thought there was a hidden code behind the Bible words to reveal the truth. It happened that, as science progressed no one could find evidence for god. Laplace was asked by Napoleon why he did not mentioned god in his book. He answered: “I had no need of such hypothesis”. Einstein had a very specific notion of god, as some would put, close to the Espinoza view. Not a personal god, not remotely alike the christian god. It is safe to say he would be an atheist if he lived today.


Question: How do atheists explain that 6.5 billion people have evidence for Allah’s existence?

Answer: It is not enough to say they have evidences for Allah’s existence. They have to show that evidence first. Then I would try to explain.


Q&A Science 01

About this

These are collected answers I wrote for sites on Questions and Answers, like Quora. I tried to remove duplicates but some may be left still.

Science

Relativity Theory

Question: How does the Theory of General Relativity work?

Answer: To talk about time we need a way to measure time, the same as a way to measure distances (space). Relativity says all clocks (and rules) will change in moving systems or close to a massive body. It is natural that we expect time and space to be independent on movement because we live in a world of slow speeds (compared to the speed of light). Relativity says that the distance between two points in space (the size of a rule, for instance) is not constant as it is in Newtonian mechanics. To build another constant thing, one that is invariant with motion, you need to include time in your measurement (this is the special theory). Points (x, y, z) are replaced by “events” (x, y, z, t) (where and when) and the interval between two events is now a constant of motion.

To describe gravity Einstein made a generalization of this concept. The “metric” of spacetime (the way to measure distances between two events) changes in the presence of matter (or energy, all the same). The theory says time slows down close to a planet or star (and space shrinks). In this framework time is just another aspect of space. Those statements seem strange but all the predictions of relativity (special and general) have been confirmed by experiments with great precision. So it is a mathematical perfect framework that describes nature in a correct way. This is called a “theory”.

The general theory, together with observations some general assumptions (as homogeneity and isotropy of space, also observed to some degree) leads to a model which includes the Big Bang and a finite age for the universe. The 13 plus something billion years is the time as measured by a “comoving” observer, floating away with the galaxies.
No one expects the theory to hold in any situation. We know already it is not good for very small things that need quantum mechanics. And the theory itself predicts situations in which it fails ( in singularities as black holes or the beginning of the universe).

By the way, there is a good theory that puts quantum mechanics and special theory together, a relativistic quantum theory. It predicts, for instance, the existence of antimatter. There is no good theory yet mixing quantum mechanics and general relativity and this is, I think, the main open problem in theoretical physics.


Question: If somehow I was able to throw a rock at the speed of light towards the sun, would it reach the sun?

Answer: You can’t because no massive body can travel at the speed of light. But, supposing just for fun, you could, the rock would hit the Sun literally “in no time” for there would not be enough time for the heat to warm the rock.
As mentioned in another comment, it is hard to predict what would happen then, because a rock traveling that fast would carry huge amount of energy. Also it would traverse the sun fast … I don’t know what would happen to the sun. (Good example of how accepting unreasonable arguments may lead to weird answers!)


Question: I have heard some people claim Einstein was a fraud. Is there any truth to that claim?

Answer: I think Einstein was brought to public attention for some other reason than purely his science. He was kind a celebrity, friend of Charles Chaplin and many other famous guys. Relativity is pretty much something hard to grasp in terms of everyday experience (so is quantum mechanics). He and his theory became a target for all kinds of nutcrackers. Whoever proves Relativity wrong will be instantly famous.


Question: Is it possible to have a unified theory of everything?

Answer: This is exactly what most theoretical physicists are trying to do. This project has been carried for the last 100 years or so. Needless to say, no success! The main problem is the severe difficulty of putting gravity in the same picture as the other 3 force fields.

We have a pretty sound description of gravity as curvature of space-time (Einstein theory), and for the electromagnetic, weak and strong nuclear in the quantum field theory, mostly done by exchange of virtual particles between interacting objects.
But there is not yet a means of putting the two together.

String theory is one of such attempts. There are many other approaches, one of them considering that gravity is not a real force (not like the others) and formulating quantum field theory in curved space-time – but this is also hard to do.

I would guess there such a theory exists and will be found. I also think math is in the very kernel of everything that exists. But this is a believe, although all we have seen so far supports this idea.


Question: Is there any alternative to the multiverse theory to explain the fine tuning of the cosmological constant?

Answer: An infinite universe with different set of constants in different parts may do the job. Also there may be unknown reasons for some or all of the constants. For example, the square in 1/r^2 for electromagnetic and gravitational forces decay may just be due to geometric reasons (since the area of a sphere around charges grow with r^2.)
We should be clear about things we don’t know and not fear them at all. It will be a sad time when people can not think of open questions.
Even the multiverse hypothesis is very speculative and should not be considered an answer.
For this reason I believe we should call it a hypothesis and never a theory.


Question: Is the gravity theory by Newton true?

Answer: There is no such a thing as “true” in science.
Newton’s theory of gravity, the same as Newtonian mechanics, works really well to describe non relativistic phenomena (weak gravitational fields, low speeds compared to the speed of light).
Otherwise we need to extend the theory (Einstein did it for us, with a little help from his friends, Michelson and Morley, Minkowsky, Riemann, …).
Special and General relativity have worked very well so far to describe all known phenomena. No one knows it will hold true for extreme environment, like very strong gravitational fields and very high energy particles. Probably not!


Question: What is the speed of gravity?

Answer: Photons, and thus light, are excitation of the electromagnetic field. Gravitational waves (and gravitons in case the gravitational field is ever quantized) are excitation of the gravitational field. According to the Relativity theory these waves travel with the speed of light. I am not aware of the status of the experimental (observational) detection of these waves and its speed.


Question: Does light have a gravitational field?

Answer: Light is made of photons which have zero rest mass (or energy, the same). In movement, which it is always, it has mass which, in turn, is the source of gravitational field. The same is true about any other field. If it has energy it has mass.


Question: Why is E=MC^2 so popular?

Answer: First, because it is a simple and compact equation. Easy to remember. Actually it is part of a much more complex equation.

Second, it conveys a deep meaning. Matter and energy are not separate entities but aspects of a higher entity (which we call matter-energy, for lack of a better term). That part is harder to fully understand.

Third, it is very useful and helps us understand many phenomena that occurs daily in ordinary life. They go from nuclear reactions inside stars or nuclear energy plants to chemical effects.


Question: What is the difference between a year and a light year?

Answer: In the language of relativity, special or general, the distance travelled by light in one year and the time taken is one and the same thing.


Question: How do physicists say that Einstein’s theory of relativity breaks down in the interior of a black hole when it is not possible to make observations of the interior of a black hole?

Answer: The equations break down. Some physical properties go to infinite at the singularity. Density, for example. I don’t think there many, if any, physicists who believe the equations are correct at this level. It would probably be necessary a quantum version of relativity at this level.


Question: It is true that science knows nothing about gravity? We still have to realize how it exists and what causes it.

Answer: No, it is not true that “that science does not know nothing of gravity”. Actually we have a pretty good description of gravity both in classical terms and relativity. (The classical case is the limit of the later, when fields are not too strong).

General Relativity is a very clear and precise theory. It describes gravity as a change in geometry of space-time, caused by matter-energy. Unfortunately it is not consistent with the quantum theory of fields that describe the other known 3 fields (weak and strong nuclear and electromagnetic).

We sure have a problem there. There is not yet a quantum theory of gravitation. But that doesn’t mean we know nothing.


Question: Do all modern theories of physics have the same concept of time?

Answer: No. The main accepted theories are built on 3 different concepts of time.

Classical physics and quantum theory (the non relativistic portion, as Schrodinger equation) use the universal time, the same proposed by Newton in his mechanical theory. It is time as an universal flow, independent of space or anything that happens in space.

Electromagnetism and relativistic quantum theory use the same time concept as special relativity, an entity correlated with space. Still a flat (Minkowsky) space-time.

General relativity stands alone with a curved spacetime.


Quantum Theory

Question: Is nature really quantized or is quantization imposed by the mathematical and technological tools used to study natural phenomena?

Answer: Nature is really quantized. All we see in the macro world is an average of many quantum measurements. That means even properties we see with our common perceptions are made of, in principle, of quantum measurements.


Question: Would it be possible to set up a real Schrödinger’s cat experiment?

Answer: Yes, but you would have to kill many cats!


Question: Is quantum physics mostly theory, or has much of it been proven?

Answer: If it is a theory, it has been proven.


Other Topics in Physics

Question: How did the Arabian culture influence Eastern Europe through the ages?

Answer: During the middle ages most classic books (specially Greek works) were destroyed due to christian bigotry. Most books we have today were kept by the Arabs. There were a time when Arabian culture was much more advanced in terms of math and science than European culture. Renaissance was possible because of the Arabs.


Question: Where does the earth get the energy to revolve around the sun?

Answer: By conservation of angular momentum the Earth (and all the other orbiting objects) doesn’t need to receive any energy to keep on rotating. The reason it was first put in motion is a bit more complicated and it has to do with the way the galaxy and later the solar system was formed. The make it short a rotating disk of particles around te Sun gather into blobs (planets) also rotating.


Question: What are some obvious truths that are rarely acknowledged?

Answer: 42.


Question: What beliefs, if any, do we need to do science?

Answer: What about Occam’s razor? Is it a belief? Do we need it?


Question: Why do some of us question authority?

Answer: Some people may know a bit more than you do, in some areas. No one knows everything. No one should be considered an authority except in their areas of expertise (like a doctor in medicine).


Question: How do you explain that it’s the Earth that is rotating on its axis and revolving around the Sun, and not the Sun revolving around the Earth, to someone who is not that educated?

Answer: Just say they are orbiting one another. Since the Sun is much larger and massive, it doesn’t move much from its position.


Question: Where could a person feel the maximum gravity on earth?

Answer: At the sea level. If you can be in a rocket speeding upwards it will be even better.


Question: When a stone is dropped from a high tower, does it land at the foot, to the east (before), or west (behind the Earth’s rotational motion)?

Answer: It lands close to the point below the release point. The rock was rotating with earth before being released. It has angular momentum. But, some fictious forces may deviate the movement, just the kind that moves the Foucault pendulum.


Question: Who are the most famous scientists who believe in god?

Answer: Most scientist in the past were believers. People like Newton did their studies in order to prove “the glory of god”. But they could not do it and eventually people, like Laplace, begun to realize god was not a good hypothesis. So, slowly, most scientist begun either to disbelieve or to try to keep separate religion and science.


Question: Is our mathematics somehow constrained by the laws of physics? If so, could there possibly be alternate universes where the mathematics is completely alien to anything we know?

Answer: I think it is the other way around: Physics, as we understand so far, has to comply with math rules. Math alone is like a game were you can do whatever you want as long as you follow the rules (logic, internal coherence, etc!) Not all of math will be ever be used in physics or in any other application.


Question: Why don’t math professors explain things logically?

Answer: I had good teachers in college, can’t complain.
I think the choice and approach in basic math is very badly done. It makes math too hard and mostly useless (at least to the level most students can grasp). If you disagree ask anyone, who is not working with any aspects of math, what they remember from their courses…

I would point as example the very long calculations with trigonometric functions when all you need is the definition of sine, cossine and tan. In a certain aspect these functions are natural and should be very easy to understand. (I know they don’t look easy…!)

I’ve heard people saying that the modern math reform is to blame for all this. I disagree. What happens is that modern math, still now, have not been fully implemented in teaching curricula. If, when in fundamental level, you can grasp the concept that math IS the study of sets, the relations between elements of the set and between elements of different sets … you are doing good enough.


Question: What is the prime difference between mathematicians and physicists?

Answer: The main difference is that physicists do math with an eye in the “real world”. A theory may be mathematically right but wrong consequences when applied to nature.


Question: Will we ever be able to calculate the size of the universe, and if so, what data do we need before we can do it?

Answer: Hum, we might. And might not! Today we don’t even know if it is finite or not. We can have good estimates of how big is the observable universe and that may be (and is probably) the best we can ever know. Anything that is beyond has no causal relation to us and so, for all practical reasons, is just not inside OUR universe.
Bad thing about all this is that people talk about speculative hypothesis, like multiverses, as if they were proved theories.


Question: What are some software or anything else recommendations, besides Word or OneNote, that I can use to easily take mathematics and physics notes?

Answer: Latex is the (only) answer.
You can use a simple ASCII editor like Notepad to write text, then compile it into beautiful final texts. You would need to learn latex syntax to write things like
E = \frac{mc^2}{\sqrt{1-\frac{v^2}{c^2}}}

In case you do not feel like doing this use a Latex editor.

On the paid side of the software world (belief it or not some people like to pay for software even when you have equal or better quality free and open source similar) you can use Scientific World. It is a WYSIWYG editor (you see, as you type) rendered math on the screen.

There are many free and open source editors. I like Lyx and TexMacs. In any case I suggest you take some time to learn shortcuts for math editing.
Besides being powerful and fun to use either will give you latex sources (which are the only thing used in the scientific community to share docs.)


Question: Can mathematics majors become theoretical physicists?

Answer: Yes, sure. But it is more difficult then doing the inverse, going from physics to math, in my opinion. The reason is the arduous path to learn quantum mechanics. A physics major takes around two years in courses about QM. There is no single discipline in math that takes so long to be grasped.
So, take some time to learn QM. And don’t believe those who say you can pass by only with relativity theory (special and general) which is not a quantum thing and takes much less time and effort to learn.


Question: What on Earth weigh exactly 0.00 pounds?

Answer: Just get any thing at all with adjustable density and make it with the exact density of the air where you make the measurement.


Question: Why is Maxwell considered at Newton’s and Einstein’s level?

Answer: I would remember that Maxwell did (maybe the first) great unification in physics, theoretically speaking. He wrote the full set of equations showing that electricity and magnetism are but different aspects of the same phenomenon.

With this he inaugurated a trend that follows to our days. Now we have a decent unified description of electromagnetic, weak and strong nuclear forces. On the other hand Einstein described gravitational interactions and his theory is in excellent agreement with observational data. BUT there is no theory so far unifying gravity with the other 3 forces.


Question: Can you solve complex math or physics problems only by using intuition?

Answer: Quite often people can tell of a bunch of mathematicians, physicists and others who came out with complex solutions off the box, attributed to intuition alone. But those who have these insights are in fact those who are working hard in a problem, sometimes for years. Intuition is a nice thing and I suppose some have it more then others. But it never came without effort and hard thinking.

A quote attributed to Einstein: “Science is 1% inspiration and 99% perspiration.”
(I could not find out if he really said this!)


Question: How do I prove the flat earth theory?

Answer: We see some questions are wrong by themselves. The Flat Earth “thing” (at best a hypothesis) is not a theory just because it cannot be proven. At the same time it is very easy to disprove the claim, as did Eratosthenes of Cirene in Greece, born about 276 BC. He made a rough estimate of the radius of Earth.

I believe all this talk about flat earth was first proposed, in modern times, as a hoax by someone trying to be funny. But now I see people from everywhere who look serious about that hoax.


Question: How can string theory be called a theory when it’s not experimentally proven? This use diminishes the value of the word theory and enables the phrase it’s just a theory to be used for well-supported theories i.e. creationist’s view on evolution.

Answer: I agree. It should be called The String Hypothesis, or Conjecture.



Question: Who do you think was more impressive, Newton or Einstein?

Answer: I don’t think it is possible to make such a comparison. Newton had his mind filled with superstition. He spent quite a bit of his time studying the Bible and alchemy. It is impossible to say how far he would go if he had spent most of his time with physics and math. On the other hand science as a whole was much simpler at his time.


Question: When reading Maxwell, Faraday, Lord Kelvin and more recently Nikola Tesla and Richard Feynman, all of them compared to others, seem to explain quite complex phenomena with words and without exclusively relying on mathematics. Why?

Answer: There is no proper way to fully describe physical phenomena without math. People can give good descriptions of the theories, better if they understand them well. But there will always be something missing. That means: learn math – at least calculus, of you want to learn physics.


Question: How deep is Deepak Chopra’s understanding of quantum physics?

Answer: When questioned by Richard Dawkins and Leonard Mlodinow, Chopra has agreed to say he talks about quantum stuff as metaphors only. That would be fine if he is clear to everyone about that. The issue is a very serious one since you can make lots of money just working against general understanding of modern physics, which is already very little among the general public.


Question: Why are so many men, usually white males, are jealous of Deepak Chopra and his work on spirituality?

Answer: I don’t know enough about people who disagree with Chopra to conclude they are mostly “white males”. My own problem with him is the very unscientific use of physics (mostly “quantum physics”) to endorse his concepts. There are many people working hard to bring good science education to the general public. We can’t be happy with those who work against it.


Question: Is evolution still a theory?

Answer: Evolution is a fact observed in nature. The explanation that evolution occurs by random mutations and natural selection is a theory. Be sure you understand what is a theory in science.


Question: Which forces does not exist in nature?

Answer: This is not really a well posed question. There is an infinity number of not existent things.

There are only 4 types of forces recognized by science, so far.

  • Electromagnetic
  • Gravitational
  • Strong Nuclear
  • Weak Nuclear

It is a good exercise to explain, in your mind, all kinds of interactions you see in nature in terms of these 4 fields.

It is not impossible that a new force may be found one day in the future. If you find it, you’ll probably get a Nobel Prize.


Question: Why does regular matter carry so little charge?

Answer: It is not true that matter carries little charge. It happens that most blocks of matter carries equal amount of positive (protons) and negative (electrons) charge so they cancel each other. To see electrical effect you have to strip some electrons, which is usually easier them strip protons.


Question: Is negative energy stronger than positive?

Answer: There is nothing as negative energy in physics.


Question: Was Newton jealous of Einstein?

Answer: Only if he could foresee the future!


Qual é a importância da ciência?

Essa pergunta foi feita por um usuário e respondida por mim no site Quora em português.

Existem várias maneiras de considerar a questão. Se olharmos para a história da ciência fica claro que a maioria dos primeiros pesquisadores buscavam resolver problemas práticos do dia a dia. Se você faz um estudo por conta própria para descobrir qual a melhor isca para usar em sua pescaria, ou a melhor forma de lança para caçar mamutes, você está fazendo ciência.

É claro que a conhecimento avançou muito e hoje a ciência de ponta é difícil e raramente feita por indivíduos sem um treinamento específico. Ao longo do tempo muitos problemas foram resolvidos, por exemplo através de medicamentos e vacinas. A sociedade hoje é 100% dependente de conhecimento avançado que coloca satélites em órbita e cria grandes redes de comunicação.

Com frequência a solução de um problema cria outros problemas que, idealmente, seriam menores que os originais e, quase sempre, exigem mais ciência para a sua solução. Ocorre também a geração de grandes problemas, como foi o caso da produção de medicamentos que causam deformidades em fetos.

Em maiores escalas alguns problemas criados pela tecnologia são enormes e podem, inclusive, determinar o fim da sociedade como hoje conhecemos. Isso acontece com o problema meteorológico do aquecimento global, da proliferação das super-bactérias ou das armas que podem alterar drasticamente a vida no planeta. Não está claro se poderemos resolver esses grandes problemas com mais tecnologia, se teremos que abandonar alguns aspectos da tecnologia ou se simplesmente não seremos capazes de resolvê-los.

Não está claro se poderemos resolver esses grandes problemas com mais tecnologia, se teremos que abandonar alguns aspectos da tecnologia ou se simplesmente não seremos capazes de resolvê-los.
Zenão
Zenão de Eléia (~450 a.C.) foi um dos primeiros pensadores a propor problemas baseados no conceito de infinito. Leia: História do Cálculo.

Ainda que a maior parte do esforço e investimento em ciência busquem resolver questões práticas, em geral com alto interesse financeiro, muitos pensadores, desde o início, se dedicaram a resolver questões com o interesse no conhecimento e sem aplicação prática imediata. Em alguns casos as respostas se mostraram mais tarde relevantes nas aplicações, em outros não, pelo menos até o momento. Fato é que humanos não se contentam em olhar para o mundo, no planeta ou no cosmos, sem fazer perguntas básicas sobre o que está e como está acontecendo. Desse ângulo, dispensar a ciência seria uma violação muito grave de um anseio humano natural.

Existe hoje um problema gravíssimo envolvendo ciência, tecnologia e educação. O avanço do conhecimento tornou as disciplinas muito complexas e de difícil compreensão. Pouquíssimas são as pessoas com a capacidade de transitar por mais de uma área científica. Isso exige longos períodos de aprendizado, que fazemos nos bancos de escolas. No entanto não conseguimos, como sociedade, gerar um ensino de qualidade e abrangente para todos. Em praticamente todas as partes a possibilidade de boa formação define a estratificação dos níveis sociais.

A ignorância e o sentimento de exclusão de quem não conseguiu atingir uma compreensão razoável de nossa sociedade ultra-complexa tem gerado uma cultura dos excluídos, o que envolve uma multidão de pessoas dedicadas a pseudociência, teorias conspiratórias e religiões oportunistas. Um exemplo são as pessoas que recusam os programas de vacinação colocando toda a população restante em risco.


Para os terraplanistas o Sol e a Lua são luminares, lanternas pequenas e próximas do disco. A alternância de dias e noites e as fases da Lua ocorrem porque essas lanternas se movem circularmente sobre a superfície. Para eles a gravidade é um problema pois produziria atrações diferentes daquelas observadas. No caso do disco finito a atração gravitacional estaria sempre voltada para o centro do disco e quem estivesse nas proximidades do polo sul seria atraído para baixo e para dentro do disco.Por que existem terraplanistas?

Diferente do que se costuma afirmar não existe ciência nem tecnologia desprovida de ideologia. Isso pode ser visto com clareza nas situações onde o dono de uma fábrica compra um equipamento que automatiza a produção dispensando muitos funcionários. Embora seja correto dizer que a tecnologia aumentou enormemente a produção de alimentos, também é correto que a distribuição desses alimentos não foi generalizada e parcelas enormes da população humana passam fome.

… sistemas educacionais devem ser abrangentes para levar a todos a conhecimento e o interesse na solução dos problemas modernos…

A meu ver precisamos de mais ciência e tecnologia, acopladas com discernimento e entendimento global das coisas. Para isso o ensino tem que encontrar uma forma de capturar o interesse e entusiasmo dos jovens, ao mesmo tempo em que os sistemas educacionais devem ser abrangentes para levar a todos o conhecimento e o interesse na solução dos problemas modernos.


A tomografia por emissão de pósitrons PET é uma técnica para obter imagens internas do corpo utilizando substâncias radioativas. Diferentes traçadores são usados para diversos fins de imagem, dependendo do processo alvo dentro do corpo.A tecnologia PET utiliza átomos instáveis que liberam energia sob forma de radiação, principalmente fótons de alta energia na forma de raios gama. A tecnologia PET se utiliza da liberação de partículas denominadas pósitrons, que são as antipartículas (antimatéria) do elétron.

 

O que você pensa a esse respeito?
Deixe a sua resposta e procurarei responder e inserir a sua opinião aqui no site.

Informe se você quer deixar visível a sua identidade.

 

Volte para o índice da Página das Perguntas.

Flet: Exemplo 1


Flet, exemplos 1

Usando métodos para alterar propriedades de widgets

Os valores de propriedades dos widgets (exceto aqueles que são de leitura somente) podem ser alterados dinamicamente pelo código e por ação do usuário. O código abaixo, além de inserir cidades previamente digitadas em uma lista, permite que usário insira novos nomes.

1   import flet as ft
2   import time
3   
4   def main(page=ft.Page):
5       def inserir(e):
6           txt = txt_cidade.value.strip()
7           if txt:
8               page.controls.append(ft.Text(txt))
9               txt_cidade.value = ""
10              page.update()
11  
12      page.add(ft.Row([ft.Text("Estas são cidades brasileiras")]))
13      txt_cidade = ft.TextField(label="Sua cidade")
14      page.add(
15          ft.Row([
16              txt_cidade,
17              ft.ElevatedButton(text="Insira o nome de sua cidade!", on_click=inserir)
18          ])
19      )
20      cidades = ["Belo Horizonte","Curitiba","São Paulo","Salvador","----------"]
21      for i in range(len(cidades)):
22          page.add(ft.Text(cidades[i]))
23          time.sleep(.5)
24  
25  ft.app(target=main)
Figura 1

Na linha 17 atribuímos uma função ao evento on_click do botão. Essa função é disparada com o clique, enviando o parâmetro e que tem várias propriedades, não utilizadas aqui. A função inserir(e) coleta o conteúdo de txt_cidade, a caixa de texto definida na linha 16, remove espaços em branco nas bordas da string, testa se ela é uma string não vazia e, se não for, cria e insere um texto na página com o conteúdo digitado pelo usuário. Lembrando, na linha 7, if txt só retorna falso se txt for uma string vazia. A execução desse código produz o resultado mostrado na figura 1, após a inserção de nova cidade pelo usuário.

Alterando texto e cores de botões

Outro exemplo abaixo mostra dois botões associados a métodos diferentes, com a capacidade de alterar as propriedades do outro botão.

1   import flet as ft
2   import random
3
4   def main(page: ft.Page):
5       cores = {0:"black", 1:"#1D74FF", 2:"#C51709", 3:"#FFE000", 4:"#00CB4F",
6                5:"#A866DC", 6:"#FF6600", 7:"green", 8:"#145375"}    
7
8       def mudar(e):
9           bt2.disabled = not bt2.disabled
10          bt2.text = "Mudar cor: desabilitado" if bt2.disabled else "Mudar cor: habilitado" 
11          bt1.text="Habilitar" if bt2.disabled else "Desabilitar"
12          page.update()
13
14      def mudar_cor(e):
15          bt1.bgcolor = cores[random.randrange(0,8)]
16          page.update()    
17
18      bt1 = ft.FilledButton(text="Desabilitar", width=250, on_click=mudar)
19      bt2 = ft.ElevatedButton("Mudar cor: habilitado", disabled=False, width=250, on_click=mudar_cor)
20      page.add(ft.Row([bt1, bt2]))
21
22  ft.app(target=main)

Um clique no botão 2 muda a cor do botão 1 escolhendo aleatóriamente entre as cores do dicionário cores. Cliques no botão 1 alternam a habilitação do botão 2.

Figura 2

Fontes, pés de página e referências a widgets

No próximo exemplo definimos duas fontes (de caracteres) para uso no aplicativo, que denominamos respectivamente por Kanit e Karma. A propriedade page.fonts é um dicionário com o nome e local do recurso, a primeira definida como um recurso externo por meio de uma URL, a segunda um recurso interno, na máquina onde roda o aplicativo, explicado abaixo.

A linha 68 define um flet.BottomSheet, uma janela modal (que impede a ação sobre outras partes do aplicativo), que pode ser usada como uma alternativa para uma janela modal ou de menu.

1   import flet as ft
2   
3   def main(page: ft.Page):
4   
5       page.title="Exibindo notas ocultas"
6       page.fonts = {
7           "Kanit": "https://raw.githubusercontent.com/google/fonts/master/ofl/kanit/Kanit-Bold.ttf",
8           "Karma": "fonts/Karma-Regular.ttf",
9       }
10      page.theme = ft.Theme(font_family="Kanit")
11      page.update()
12      
13      def exibe_mensagem(txt):
14          mensagem.value=txt
15          mensagem.update()
16  
17      def traduzir(e):
18          bt2.data = (bt2.data + 1)%2
19          conteudo.current.value = texto_nota[bt2.data]
20          page.update()
21  
22      def bs_fechado(e):
23          exibe_mensagem("A nota foi ocultada por clique fora de sua área.")
24  
25      def mostrar_pe(e):
26          bs.open = True
27          bs.update()
28          exibe_mensagem("A nota está exibida.")
29  
30      def ocultar_pe(e):
31          bs.open = False
32          bs.update()
33          exibe_mensagem("A nota foi ocultada por clique no botão interno.")
34  
35      def fechar_app(e):
36          page.window_destroy()
37  
38      texto_nota=[(
39          'The Selfish Gene is a 1976 book on evolution by ethologist Richard Dawkins, in '
40          'which the author builds upon the principal theory of George C. Williams\'s '
41          'Adaptation and Natural Selection (1966). Dawkins uses the term "selfish gene" as '
42          'a way of expressing the gene-centred view of evolution (as opposed to the views '
43          'focused on the organism and the group), popularising ideas developed during the '
44          '1960s by W. D. Hamilton and others.'
45      ),
46      (
47          'O Gen Egoísta é um livro de 1976 sobre evolução do etólogo Richard Dawkins, no '
48          'qual o autor se baseia na teoria principal de Adaptação e Seleção Natural de '
49          'George C. Williams (1966). Dawkins usa o termo "gene egoísta" como forma de '
50          'expressar a visão da evolução centrada no gene (em oposição às visões focadas no '
51          'organismo e no grupo), popularizando ideias desenvolvidas durante a década de '
52          '1960 por W. D. Hamilton e outros.'
53      )]   
54  
55      bt1=ft.ElevatedButton("Fechar a nota", on_click=ocultar_pe)
56      bt2=ft.ElevatedButton("Traduzir", data=0, on_click=traduzir)
57      bt3=ft.ElevatedButton("Exibir pé de página", on_click=mostrar_pe)
58      bt4=ft.ElevatedButton("Fechar Aplicativo", on_click=fechar_app)
59  
60      mensagem=ft.Text("A nota não está exibida.", font_family="Karma", size=20)
61      conteudo=ft.Ref[ft.Text()]()
62      coluna_texto=ft.Column([ft.Text(ref=conteudo), ft.Row([bt1, bt2])])
63      conteudo.current.font_family="Karma"
64      conteudo.width=600
65      conteudo.current.size=20
66      conteudo.current.value = texto_nota[0]
67  
68      bs = ft.BottomSheet(ft.Container(coluna_texto, padding=50), open=False, on_dismiss=bs_fechado)
69  
70      page.overlay.append(bs)
71      page.add(
72          ft.Text("Clique no botão para exibir a nota oculta", size=30),
73          mensagem,
74          ft.Row([bt3, bt4]),
75      )
76  
77  ft.app(target=main, assets_dir="assets")
Figura 3: posição das fontes

A linha 77, que inicializa o aplicativo do flet, informa que estamos usando o diretório de recursos assets_dir=”assets”, onde podemos armazenar imagens, fontes e outros recursos. No caso do atual aplicativo o diretório code é a pasta raiz, de onde o código será executado. A fonte local Karma-Regular.ttf está gravada em code/assets/fonts/Karma-Regular.ttf, como mostrado na figura 3. Ela é inserida no dicionário page.fonts da linha 6 e utilizada nas linhas 60 e 63. A outra fonte é definida como padrão do aplicativo na linha 10.

A linha 68 inicializa o bs = BottomSheet, inicialmente fechado (invisível). Esse widget é exibido com o clique do botão bt3 (linha 57) e fechado com bt4 (linha 58). O BottomSheet é inserido na página com page.overlay.append(bs) (70). page.overlay é uma lista de controles que são exibidos por cima dos demais controles da página. O botão bt2 (traduzir) altera a exibição do texto em conteudo, escolhendo entre os dois textos armazenados na lista texto_nota. O índice do texto exibido a cada momento está armazenada na propriedade bt2.data.

Outro ponto digno de nota é o uso da referência para um controle usada na linha 61 em conteudo=ft.Ref[ft.Text()](). A classe Ref permite que se defina uma referência para um controle. No cao a referência é feita ao controle de texto associado à variável conteudo. Essa referência permite o uso posterior das propriedades e eventos do controle. Para lidar mais tarde com esse controle usamos a propriedade current como é feito nas linhas 66 e 19.

O resultado desse código ao ser executado é mostrado na figura 4, antes de pressionado o botão Exibir pé de página. A figura 5 exibindo o texto em inglês após pressionamento do botão. Um texto alternativo, em português é exibido quando se clica em Traduzir.

Figura 4: Aplicativo antes de exibir a nota.
Figura 5: Exibindo o texto da nota.

Shebangs e Python no Windows


O que é um Shebang


Vimos que podemos executar comandos do python diretamente no interpretador, obtendo resultados imediatos. Também podemos gravar um arquivo contendo um Shebang #!na primeira linha, informando qual é o interpretador a ser usado nessa execução. Esse conteúdo pode ser lido no artigo Módulos e Pacotes, nesse site. Um exemplo simples pode ser o listado abaixo, gravando o arquivo teste.py.

#!/usr/bin/python3
print("Aprendendo Python no Phylos.net!")

Para executá-lo basta escrever no prompt do terminal, lembrando que, por default arquivos não pode ser executados diretamente por motivos de segurança (pois podem conter instruções maliciosas para o sistema). Eles devem ser tornados executáveis com chmod +x arquivo, o que dá permissão para todos os usuários e todos os grupos.

# a arquivo deve ter permissão do sistema para ser executado como programa
$ chmod +x teste.py
# depois:
$ ./teste.py
# alternativamente podemos executar (sem o #!)
$ python3 /caminho/completo/para/teste.py

# uma única linha no prompt de comando pode ser executada usando a opção -c
$ python3 -c 'print(2*67)'
↳ 134
#
$ /usr/bin/python -c 'print("Usuário")'
↳ Usuário
$ echo $PATH
↳ /var/home/usuario/.local/bin:/var/home/usuario/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin

No caso do comando /usr/bin/python3 o caminho completo para o interpretador (ou um link simbólico para ele) foi fornecido. A linha python3 -c ‘print(2*67)’ também funciona porque python3 está no PATH, o que pode ser verificado com echo $PATH, como mostrado acima.

Se um shebang não for incluído o sistema tentará executar o código na linguagem de comandos da própria shell, por exemplo a BASH shell.

Para que o script somente seja executado se for chamado diretamente do terminal modificamos teste.py usando a variável global __name__. Nada será executado se ele for chamado como módulo. Normalmente não colocamos um shebang em um módulo do Python contendo funções e definições de classes.

#!/usr/bin/python3

if __name__ == "__main__":
    print("Aprendendo Python no Phylos.net!")

O shebang indica, através de um caminho absoluto, onde está o interpretador do Python, lembrando que ele pode variar em cada instalação. Caminhos relativos não são permitidos. Esse escolha aproveita o fato de que o sinal # (cerquilha ou hash, em inglês), representa um comentário no python e em várias outras linguagens de programação.

Essa notação é válida em shells Z shell ou Bash, que são usados em sistema como o macOS e Linux. No Windows ela é ignorada, sem causar danos. Para usar shebangs no Windows você pode instalar o Windows Subsystem for Linux (WSL). Podemos também associar globalmente no Windows arquivos com uma certa extensão (.py nesse caso) e um programa que o executará (como o interpretador Python). Mais sobre Python no Windows abaixo.

Shebang portátil


Como vimos um shebang deve conter o caminho completo (e não relativo) para o interpretador. Dessa forma se o código for executado em outro computador onde o interpretador esteja em local diferente, ele falhará em sua execução.

Para contornar essa questão podemos usar o comando (um aplicativo executável) env (ou printenv) que exibe as variáveis de ambiente (do environment). Se usado sem parâmetros ela simplesmente lista todas as variáveis definidas. Se usada com um parâmetro (no nosso caso o python3 ele indica a posição do interpretador e o acionada, como mostrado no código.

$ env
SHELL=/bin/bash
SESSION_MANAGER=local/unix:@/tmp/.ICE-unix/2035,unix/unix:/tmp/.ICE-unix/2035
COLORTERM=truecolor
...  truncado ...
_=/usr/bin/env

# a última linha mostra onde está esse aplicativo
$ whereis env
env: /usr/bin/env /usr/share/man/man1/env.1.gz

# usado com um parâmetro
$ /usr/bin/env python3
Python 3.12.0 (main, Oct  2 2023, 00:00:00) [GCC 13.2.1 20230918 (Red Hat 13.2.1-3)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>


Nota: Por convencão o arquivo binário env (ou printenv) será sempre encontrado em /usr/bin/. Sua função é localizar arquivos binários executáveis (como python) usando PATH. Independentemented de como o python está instalado seu caminho será adicionado a esta variável e env irá encontrá-lo, caso contrário o python não está instalado. Ele é usado para criar ambientes virtuais, configurando as variáveis de ambiente.

Como resultado desse comportamento podemos escrever um shebang que encontra e executa o interpretador onde ele estiver. Para isso gravamos o arquivo teste.py da seguinte forma:

#!/usr/bin/env python3
print("Uma forma portátil de shebang!")

Como exemplo, podemos executar código em python 2 e python 3 informando qual interpretador queremos usar.

# gravamos 2 arquivos
# python_2.py
#!/usr/bin/env python2
print "Esse rodou no python 2"

# python_3.py
#!/usr/bin/env python3
print("Esse rodou no python 3")

# e os executamos com 
$ ./python_2.py
Esse rodou no python 2

$ ./python_3.py
Esse rodou no python 3

Claro que ambas as versões devem estar instaladas. Observe que, no python 2 o print não é uma função e não exige o uso de parênteses. Podemos verificar qual é a versão do python em uso com o parâmetro -V.

$ /usr/bin/env python -V
Python 3.12.0

Nota: Na minha instalação os comandos python, python3 e python3.12 todos apontam para o mesmo interpretador. No entanto pode ser arriscado usar a forma $ /usr/bin/env python sem definir a versão pois ela pode ter significados diferentes em outras instalações.

Python no Windows

A maioria dos sistemas operacionais como o Unix, Linux, BSD, macOS e outros trazem uma instalação do Python suportada pelo sistema, o que não ocorre com o Windows. Para resolver essa situação a equipe do CPython compilou instaladores para o Windows para que se possa instalar o interpretador e as bibliotecas, para o usuário ou globalmente no sistema. Também são disponibilizados arquivos ZIPs para os módulos adicionais. As versões do Python ficam limitadas a algumas versões do Windows. Por exemplo, o Python 3.12 tem suporte no Windows 8.1 ou mais recentes. Para uso com o Windows 7 é necessário instalar o Python 3.8.

Diversos instaladores estão disponíveis para Windows, cada um com vantagens e desvantagens. O instalador completo contém todos os componentes e é a melhor opção para desenvolvedores que usam Python para projetos variados. O pacote da Microsoft Store é uma instalação simples do Python adequada para executar scripts e pacotes e usar IDLE ou outros ambientes de desenvolvimento. Ele requer Windows 10 ou superior e pode ser instalado com segurança sem corromper outros programas. Ele também fornece muitos comandos convenientes para iniciar o Python e suas ferramentas.

O pacote nuget.org instala um ambiente reduzido, suficientes para pacotes Python e executar scripts, mas não são atualizáveis, além de não possuiren ferramentas de interface de usuário. O pacote embeddable é um pacote mínimo de Python adequado para incorporação em um aplicativo maior sem ser diretamente acessível ao usuário. Uma descrição mais detalhada dos vários pacotes de instalação pode ser encontrada no documento Using Python on Windows.

Os instaladores criam uma entrada do menu Iniciar para o interpretador Python. Também podemos iniciá-lo no prompt de comando, configurando a variável de ambiente PATH. O instalador oferece a opção de configurar isso automaticamente, na opção “Adicionar Python ao PATH”. A localização da pasta Scripts\ também é inserida. Com isso de pode digitar python na linha de comando para executar o interpretador e pip para instalar pacotes. Também é possível executar seus scripts com opções de linha de comando.

A variável PATH também pode ser modificar manualmente para incluir o diretório de instalação do Python, delimitado por ponto e vírgula de outras entradas. Por exemplo ela pode ter a seguinte conteúdo:
C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Python 3.9

Inicializador Python para Windows

O lançador, ou inicializador, Python para Windows é um utilitário que permite localizar e executar diferentes versões do Python. Com ele podemos indicar dentro dos scripts , ou na linha de comando, qual a versão do interpretador deve ser usada e executada, como fazemos com o Shebang no Linux ou macOS, independentemente do conteúdo da variável PATH. O inicializador foi originalmente especificado no PEP 397.

É preferível instalar o inicializar por usuário em vez de instalações globais no sistema. Instalações globais no sistema do Python 3.3 e posteriores incluem o inicializador e o adicionam ao PATH. Ele é compatível com todas as versões do Python. Para verificar se o inicializador está disponível, execute o comando py no prompt de comando. Essa e outras formas do comando ficam disponíveis:

$ py
# inicia e mostra a última versão do Python instalada.
# Comandos digitados aqui são enviados diretamente para o Python.

# Se existem mais de um versão instalada, a versão desejada deve ser especificada:
$ py -3.7

# para Python 2, se instalada:
$ py -2

# se o instalador não estiver instalado, a mensagem será mostrada:
$ py
↳ 'py' is not recognized as an internal or external command, operable program or batch file.

# para ver todas as versões do Python instaladas:
$ py --list

Muitas vezes, principalmente quando vamos instalar diversos módulos para desenvolver scripts ou aplicativos, usamos ambiente virtuais, descritos no artigo Ambientes Virtuais, Pip e Conda. Eles podem ser criados com o módulo venv da biblioteca padrão ou virtualenv, uma ferramenta externa. Se o inicializador for executado dentro de um ambiente virtual sem a especificação explícita de versão do Python, ele executará o interpretador do ambiente virtual, ignorando o global. Caso outro interpretador, que não o instalado no ambiente virtual, seja desejado é necessário especificar explicitamente a outra versão do Python.

Por exemplo: Suponha que Pyton3 e Pyton2 estão instalados, e Pyton3 aparece primeiro no PATH. Criamos um arquivo sistema.py com o conteúdo:

#! python
import sys
sys.stdout.write(f"Estamos usando a versão do Python \n (sys.version,)")

# na mesma pasta executamos
$ py sistema.py
# informações sobre Python 3 são exibidas

# Se alteramos o código do script para
#! python2
import sys
sys.stdout.write(f"Estamos usando a versão do Python \n (sys.version,)")

# e executamos
$ py sistema.py
# informações sobre Python 2 são exibidas

# Sub versões podem ser especificadas
! python3.10
# Isso corresponde ao comando
$ py -3.10 sistema.py

Claro que é uma boa prática para desenvolvedores Windows, por compatibilidade, usar o Shebang necessário para execução nos Sistema tipo Unix.

Criando executáveis

O Python não possui suporte integrado para a construção de executáveis independentes. No entanto podemos lançar mão de algumas ferramentas, geralmente desenvolvidos pela comunidade, que resolvem esse problema de alguma forma. As mais populares são as seguintes (os ícones são links para instruções):

Cada um deles possui suas limitações e aspectos fortes de uso. Para definir qual deles usar você deve decidir qual plataforma deseja atingir, pois cada ferramenta de empacotamento suporta um conjunto específico de operações dos sistemas. É melhor que você tome essa decisão logo no início da vida do projeto. Você pode encontrar uma descrição mais precisa e completa dessas ferramentas no texto de Jaworski e Ziadé, citado na bibliografia.

Bibliografia

todos os arquivos acessados em novembro de 2023.

Leia também nesse site: