Jupyter Notebook

O que é o Jupyter Notebook?

Jupyter Notebook é uma ferramenta poderosa para o desenvolvimento projetos de ciência de dados de forma interativa que é executada de dentro de seu browser. Além da execução interativa de código ele pode ser usado para a preparação de apresentações dinâmicas onde texto pode ser bem formatado contendo imagens, gráficos interativos e fórmulas matemáticas. O conteúdo das linhas de código e seus outputs (as respostas produzidas pelo código) ficam bem delimitadas.

Ele faz parte do Projeto Jupyter de código aberto e free software. É possível baixar e instalar gratuitamente o Jupyter Notebooks separadamente ou como parte do kit de ferramentas de ciência de dados Anaconda. Com ele se pode usar vários ambientes de execução (kernels ou núcleos) com linguagens de programação como o Python, R, Julia, C++, Scheme, Haskell e Ruby.

O Jupyter Notebook está se tornando uma interface muito popular para a computação na nuvem e muitos dos provedores desse tipo de serviço o adotaram como interface front-end para seus usuários. Entre eles estão o SageMaker Notebooks da Amazon, o Colaboratory do Google e o Azure Notebook da Microsoft. O Colaboratory (também chamado de Colab) é um ambiente gratuito que armazena e roda notebooks no Google Drive.

Os arquivos no Notebook são armazenados no formato JSON com a extensão *.ipynb. Eles podem ser lidos pelo aplicativo instalado (que usa o browser para sua exibição), e exportado para várias formatos, entre eles: html, markdown, pdf, latex e slides Reveal.js. O arquivo consiste de várias células que são exibidas como uma página usual de html. Algumas células são de código e seus resultados, outras de texto, imagens ou outras mídias. Alternativamente eles podem ser lidos e exibidos (de forma não interativa) pelo nbviewer (na web).

Instalação


A forma mais simples de instalação do Jupyter Notebooks consiste em instalar o Anaconda, a distribuição Python mais usada para ciência de dados. Esta instalação inclui as princiais bibliotecas e ferramentas mais populares, como NumPy, Pandas e Matplotlib.

Para obter o Anaconda:

  • Baixe a versão mais recente do Anaconda aqui. Existem instaladores gráficos para Linux, Windows e MacOS.
  • Instale seguindo as instruções na página de download ou contidas no arquivo instalador executável.
  • ou … usuários que conhecem Python e que preferem gerenciar seus pacotes manualmente, pode apenas usar:
    pip3 install jupyter.

Executando e Criando um Notebook

No Windows na MacOS ou Linux um atalho para Jupyter Notebook é criado no menu do sistema. Caso nenhum atalho tenha sido criado você pode criar um ou iniciar usando o console. No Linux se digita jupyter-notebook no console. Uma janela com a seguinte aparência é aberta no browser padrão:

A primeira página exibe o painel de controle do Jupyter (dashboard). Ele dá acesso aos arquivos e subpastas que estão na pasta de inicialização do Jupyter. Esta pasta, no entanto, pode ser alterada. O painel de controle tem uma interface amigável por onde você pode controlar suas pastas e notebooks. Toda a descrição que usamos aqui se refere à aparência default dos notebooks. Essa aparência pode ser alterada modificando-se o arquivo css em /home/nome-usuario/.jupyter/custom/custom.css (no Linux).

O Jupyter Notebook fica aberto no navegador usando uma URL especial, do tipo “http://localhost:8888/tree”. Isso indica que o servidor dessa página esta em sua máquina local.

Você pode criar uma pasta nova para seus projetos clicando em New Folder. Depois pode renomear sua pasta selecionado e clicando em Rename. Clique na pasta para abrí-la e depois em New: Python 3 (notebook). Um notebook vazio e sem nome é criado. Clique nele e em File | Rename e dê um nome apropriado para o seu notebook. Vários notebooks podem ser abertos ao mesmo tempo.

Um notebook aberto apresenta a seguinte interface:

Os menus superiores dão acesso as funcionalidades de gravar arquivo, importar e exportar para diferentes formatos, etc. O item File | Save and Checkpoint (Ctrl-S) permite guardar o estado as sessão no momento de forma a poder ser recuperada mais tarde por meio de File | Revert to Checkpoint. Para fechar uma sessão não basta fechar a aba do navegador pois isso deixaria ativa a tarefa na memória do computador. Para isso você pode usar File | Close and Halt ou Kernel | Shutdown. Também se pode clicar em LOGOUT no canto superior direito.

Ainda na barra de menus você pode clicar em Help | User interface tour para ver alguns pontos relevantes no notebook. Help | Keyboard Shortcuts exibe os atalhos de teclado predefinidos, observando que eles podem ser modificados pelo usuário. O menu de ajuda também contém links diretos para as documentações do Python, IPython, NumPy, SciPy, Matplotlib, SymPy, pandas e markdown. O ícone de teclado abre uma ajuda com os atalhos mais usados.

Notebooks são iniciados com uma célula vazia. Cada célula possui dois modos de uso: modo de edição e modo de comando. Clicando dentro da célula ela fica com borda verde e entra no modo de edição onde se pode inserir texto e códigos. Use a caixa de seleção na caixa de ferramentas do notebook para selecionar entre ‘code’, ‘markdown’ ou ‘Raw NBConvert’. (A opção ‘heading’ está em desuso e é desnecessária). Se ‘code’ está selecionado você pode digitar um comando como, por ex.,

print('Olá galera!')
Olá galera!

Comandos dentro de uma célula de código são executados todos de uma vez. Para isso pressione:
shift-enter: o código é executado e uma nova célula é aberta no mode de edição, ou
ctrl-enter: o código é executado e a mesma célula fica selecionada no modo de comando.

Em ambos os casos o output, se existir, é mostrado abaixo da célula. O botão ▶ Run na barra de ferramentas tem o mesmo efeito que shift-enter.

Os modos de edição e de comando são alternados com o uso de ESC (passa de comando para edição) e enter (de edição para comando).

Quando no modo de comando (a célula fica com a borda azul) os seguintes atalhos ficam habilitados:

Comando Ação
ESC/enter Alterna entre modos de edição / comando
Barra de espaço Rolar tela para baixo
Shift-Barra de espaço Rolar tela para cima
A Inserir célula acima
B Inserir célula abaixo
D, D Apagar células selecionadas
Z Desfazer apagamento
Shift-L Exibir/ocultar numeração das linhas de código
Y Alterar célula para código
M Alterar célula para markdown
R Alterar célula para raw
H Exibir Help | keyboard shortcuts
Teclas 🔼 ou 🔽 Rolar para cima e para baixo nas células
Shift 🔼 ou 🔽 Selecionar várias células de uma vez.
Shift M Mesclar várias células selecionadas em uma única.
Ctrl Shift – Dividir célula ativa na posição do cursor (no modo de edição).
Shift clique na margem esquerda da célula Selecionar várias células de uma vez.

Um lista completa desses atalhos pode ser vista no menu Help | keyboard shortcuts.

Células no formato de texto

Células podem ser marcadas como texto puro, sem qualquer formatação, no modo Raw NBConvert. Esse texto é exibido como está e não passará por renderização de nenhuma forma nem na exibição dentro do notebook nem na exportação para outros formatos, como o pdf.

Markdown

Markdown é uma linguagem de marcação limitada mas bastante simples de se aprender e usar. Ela tem sintaxe diferente de html mas guarda uma correspondência com suas tags. Você pode encontrar uma descrição mais completa de Markdown na página Marcação de Texto com Markdown.

Além da marcação markdown se pode usar um conjunto restrito de tags html nas caixas de texto. Por exemplo, o código à esquerda produzirá a barra vermelha à direita, útil para marcar o ponto de parada dentro de um notebook.

parei aqui ↷
<div style=”border:1px solid black;
padding:10px; color:white; background-color:red;”>
parei aqui ↷
</div>

O Jupyter Notebook pode renderizar Latex (para isso usa a biblioteca javascript Mathjax) em suas células de Markdown.


A identidade de Euler é \(e^{i \pi} + 1 = 0\).
A definição da derivada de primeira ordem é:
$$
f'(x) = \lim\limits_{h \rightarrow 0} \frac{f(x+h) – f(x)}{h}
$$

Células de código

Células de código contém as instruções a serem executadas pelo kernel. À esquerda de uma célula de código aparece o sinal In[n] que significa Input [n], onde n é a ordem de execução das linhas. Uma célula em exibição é marcada pelo sinal In[*], o que é importante observar quando se tem uma execução mais demorada de código. Em geral o notebook continua responsivo mas novas instruções devem aguardar o término das primeiras para serem executados. O resultado da computação da célula, quando existir, aparece abaixo com o sinal Out[n].

O código em um célula ativa (com bordas azuis) é executado com ctrl-enter ou shift-enter (alternativamente com botão ▶ Run na barra de ferramentas). A barra de menu contém as opções Cell | Run All, Cell | Run All Above Cell | Run All Below.

É importante notar que as células são executadas no kernel e seu estado persiste ao longo da execução. O estado do kernel se refere ao notebook como um todo e não às células individuais. Se você importar bibliotecas ou declarar variáveis ​​em uma célula elas estarão disponíveis em toda a seção e não apenas nas células abaixo da declaração. A ordem em que inputs e outputs aparecem pode ser enganosa: se você declarar uma variável em uma célula, digamos g = 5 e voltar para uma célula anterior a variável g ainda terá o mesmo valor. O que importa é a ordem de execução, marcada por In[n]. Por isso é preciso ter cuidado ao fazer alterações nas células. Idealmente se deve manter a ordem sequencial e, ao fazer alterações importantes, executar todo o notebook novamente.

Existem várias opções relativas à execução no menu Kernel:

Kernel | Interrupt Interromper o kernel,
Kernel | Restart Reinicializar o kernel,
Kernel | Restart & clear outputs Reinicializar kernel e limpar outputs,
Kernel | Restart & Run All Reinicializar kernel e executar todas as células.

A opção de reinicializar o kernel limpando as saídas e executar novamente todas as células pode ser útil quando muitas células foram alteradas. No entanto, dependendo das operações a serem executadas, ela pode ser uma operação demorada.

É possível escolher e rodar e Jupyter Notebook com diferentes opções de kernel, com diferentes versões de Python e muitas outras linguagens, incluindo Java, C, R e Julia.

O Notebook é salvo ao se pressionar Ctrl S. Isso renova o arquivo de ponto de verificação que é criado junto com o Notebook. Esse arquivo, que também tem extensão .ipynb fica localizado em pasta oculta e pode ser usado na recuperação da sessão caso algum erro inesperado cause a perda do notebook atual. Por padrão o Jupyter salva automaticamente o bloco de notas a cada 120 segundos sem alterar o arquivo de bloco de notas principal.Para reverter para um ponto de verificação use o menu via File | Revert to Checkpoint.

Tendo escolhido um notebook com kernel python 3, podemos experimentar um resultado com a execução de código que fornece um output de texto e gráfico:

# importe as bibliotecas necessárias
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(1, 15, 0.1);
y = np.sin(x)/np.cos(x)
z = np.cos(x)/np.sin(x)
print("x em [1, 15] \ny=seno/cosseno; z=cosseno/seno")
plt.plot(x, y)
plt.plot(x, z)
x em [1, 15]
y=seno/cosseno; z=cosseno/seno

É importante observar que a última variável listada em uma célula é exibida no output sem necessidade de um comando print. Por ex., no código abaixo importamos uma tabela disponível na web no formato *.csv para a construção de um dataframe do pandas. O dataframe é exibido com uma formatação amigável no final da célula.

1  import pandas as pd
2  bfi ='https://vincentarelbundock.github.io/Rdatasets/csv/psych/bfi.csv'
3  df = pd.read_csv(bfi)
4  # head exibirá apenas as 5 primeiras linhas do dataframe
5  df.head()
Unnamed: 0 A1 A2 A3 A4 A5 C1 C2 C3 C4 N4 N5 O1 O2 O3 O4 O5 gender education age
0 61617 2.0 4.0 3.0 4.0 4.0 2.0 3.0 3.0 4.0 2.0 3.0 3.0 6 3.0 4.0 3.0 1 NaN 16
1 61618 2.0 4.0 5.0 2.0 5.0 5.0 4.0 4.0 3.0 5.0 5.0 4.0 2 4.0 3.0 3.0 2 NaN 18
2 61620 5.0 4.0 5.0 4.0 4.0 4.0 5.0 4.0 2.0 2.0 3.0 4.0 2 5.0 5.0 2.0 2 NaN 17
3 61621 4.0 4.0 6.0 5.0 5.0 4.0 4.0 3.0 5.0 4.0 1.0 3.0 3 4.0 3.0 5.0 2 NaN 17
4 61622 2.0 3.0 3.0 4.0 5.0 4.0 4.0 5.0 3.0 4.0 3.0 3.0 3 4.0 3.0 3.0 1 NaN 17

2800 rows × 29 columns

Ajuda

É sempre útil lembrar os mecanismos de se conseguir ajuda no python e no Jupyter. A função help do python é útil para se ver documentação sobre um tipo de variável ou uma bliblioteca importada. (Em ambos os casos a saída exibida está truncada.)

# ajuda sobre dictionaries
help(dict)
Help on class dict in module builtins:
class dict(object)
| dict() -> new empty dictionary
| dict(mapping) -> new dictionary initialized from a mapping object’s
| (key, value) pairs
| dict(iterable) -> new dictionary initialized as if via:
| d = {}
| for k, v in iterable:
| d[k] = v
import math
help(math)
Help on module math:
FUNCTIONS
acos(x, /)
Return the arc cosine (measured in radians) of x.
acosh(x, /)
Return the inverse hyperbolic cosine of x.
asin(x, /)
Return the arc sine (measured in radians) of x.

O comando help() usado sem argumento abre uma janela de busca interativa do tópico de ajuda.

Além disso escrever o nome de uma biblioteca, método ou variável precedido de ? provocará a exibição da docstring relativa ao item, o que é uma boa forma de conferir uso e sintaxe.

import pandas as pd
?pd
Type: module
String form: <module ‘pandas’ from ‘/home/guilherme/.anaconda3/lib/python3.7/site-packages/pandas/__init__.py’>
File: ~/.anaconda3/lib/python3.7/site-packages/pandas/__init__.py
Docstring:
pandas – a powerful data analysis and manipulation library for Python
=====================================================================
**pandas** is a Python package providing fast, flexible, and expressive data
structures [… texto truncado …]

Células e Linhas Mágicas em Jupyter

Uma sintaxe especial dos notebooks consiste em inserir comandos iniciados por %% para “mágica” na célula inteira e % para “mágica” na linha. Por exemplo %matplotlib inline faz com que gráficos do matplotlib sejam renderizados dentro do próprio notebook. Os sinais % e %%indicam respectivamente “mágica” na linha ou na célula. Digitar %lsmagic na célula e executá-la exibirá uma lista de todos os comandos mágicos de célula e de linha, informando ainda se automagic está ativado. Se automagic = ON os prefixos %% e % são desnecessários.

Alguns exemplos de “mágicas”:

Mágica Efeito
%run Roda um script externo como parte da célula.
Ex.: %run meu_codigo.py
executa meu_codigo.py como parte da célula.
%timeit Conta os loops, mede e exibe o tempo de execução da célula.
%prun Mostra o tempo de execução de uma função.
%%writefile Salva o conteúdo da célula para um arquivo.
Ex.: %%writefile meu_output.py
salva o código da célula no arquivo meu_output.py.
%%pycat Lê e exibe o conteúdo de um arquivo.
Ex.: %%pycat meu_output.py
lê o conteúdo gravada antes em meu_output.py.
%macro Define uma macro para execução posterior.
%store Salva a variável para uso em outro notebook.
%pwd Exibe a pasta default de trabalho.
%who Exibe varáveis ativas.
%matplotlib inline Exibe gráficos matplotlib inline.
%lsmagic Exibe lista de comandos “mágicos”.
%automagic Liga/desliga automagica (necessidade de %).
%%javascript Roda a célula como código JavaScript.
%%html Exibe código html renderizado.
%pdb Aciona o Python Debugger.
%<comando>? Mostra ajuda sobre a %<comando>
%%script python2
import sys
print 'Esse comando foi executado no Python %s' % sys.version
# output---> Esse comando foi executado no Python 2.7.18 (default, data / hora) 
%%script python3
import sys
print('Comando executado no Python: %s' % sys.version)
# output---> Esse comando foi executado no Python 3.8.5 (default, data / hora) 
%%bash
echo "O conteúdo de minha variável BASH: $BASH"
# output---> O conteúdo de minha variável BASH: /usr/bin/bash
# Definição de fatorial usando recursão	
def fatorial(n):
    if n == 1:
        return 1
    else:
        return n * factorial(n-1)
fatorial(40)      # resulta em 87178291200
# Claro que a mesma coisa seria obtida com a função
import math
print(math.factorial(14))    # 87178291200

Para medir o tempo de execução da célula ao rodar a função fatorial usamos %timeit

%timeit fatorial(14)

1.78 µs ± 16.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Executando comandos da SHELL

Usando o prefixo ! você pode enviar comandos diretamente para a shell de seu sistema operacional. Os comandos dependerão, claro, de seu sistema. No exemplo seguinte uso o bash do linux.

! ls *.ipynb     # vai listar todos os arquivos ipynb
! ls *.py        # lista meu_output.py gravado no exemplo anterior 

# mv é o comando bash para renomear arquivos
! mv meu_output.py novo_nome.py 
! ls *.py        # lista novo_nome.py

# Se você tem pip instalado pode gerenciar pacotes python de dentro do notebook:
!pip install --upgrade nome_do_pacote

Extensões do Jupyter Notebook


Extensões são recursos adicionais que estendem a funcionalidade dos Notebooks. Elas podem melhorar sua funcionalidade como uma IDE (um ambiente integrado de desenvolvimento), permitindo o acompanhamento de variáveis para fins de debugging, formatando o código automaticamente ou alterando sua aparência. Elas também permitem a inserção de widgets, que geralmente são objetos com representação gráfica no navegador, tais como caixas de texto, sliders e outras ferramentas interativas. Elas adicionam funcionalidades GUIs nos notebooks.

Uma extensão muito usada é a Nbextensions que pode ser instalada à partir do código seguinte, inserido no próprio notebook.

conda install -c conda-forge jupyter_contrib_nbextensions
conda install -c conda-forge jupyter_nbextensions_configurator 

A instalação de extensões pode variar de acordo com o seu ambiente de trabalho.

Jupyter Widgets

Widgets são objetos do python que possuem uma representação visual no navegador e permitem interação do usuário. Eles podem ser simples como uma caixa de texto ou um controle de arrastar, ou objetos sofisticados como os controles sobre uma tabela de dados ou sobre um mapa.

Slider é um widget útil para receber um valor do usuário por meio do mouse ou toque de tela. O objeto possui propriedades que podem ser alteradas e lidas, e métodos.
No exemplo abaixo um slider é criado, algumas de suas propriedades são ajustadas e depois é exibido.

import ipywidgets as ipw
# Inicializar um slider
slid = ipw.IntSlider()
slid.min = 0
slid.max = 50
slid.description = "Avalie:"
display(slid) # Exibe o slider ( figura a)

# O objeto pode ser inicializado com as propriedades desejadas
slid2 = ipw.IntSlider(
    value=0,
    min=0,
    max=10,
    step=2,
    description='Só pares:',
    disabled=False,
    continuous_update=True,
    orientation='horizontal',
    readout=True,
    readout_format='d'
)
display(slid2) # Exibe o slider ( figura b)

Button é um widget que pode armazenar interação do usuário em resposta binária (sim/não, por ex.).

ipw.Button (
    description='Clica aí',
    disabled=False,
    tooltip='clica...',
    button_style='success', # pode ser 'success', 'info', 'warning', 'danger' ou ''
    icon='check'
)
# Exibe o botão (figura c)

Text apresenta uma caixa de texto a ser preenchida pelo usuário:

ipw.Text (
    placeholder='Digite seu nome',
    description='Nome:',
)
# Exibe a caixa de texto ( figura d)

Progress Bar mostra uma barra de progresso:

ipw.IntProgress (
    min=0,
    max=10,
    value=7,
    description='Realizado %',
    bar_style='success', # pode ser 'success', 'info', 'warning', 'danger' ou ''
    orientation='horizontal'
)
# Exibe a barra de progresso ( figura e)

Para serem úteis as widgets devem interagir com o código. Como ex. vamos criar uma barra de progresso atribuindo o objeto a uma variável.

pb = ipw.IntProgress (
    min=0,
    max=10,
    value=7,
    description='Realizado%',
    bar_style='success', # pode ser 'success', 'info', 'warning', 'danger' ou ''
    orientation='horizontal'
)

print('valor inicial = ', pb.value) # value é uma propriedade de pb. Neste caso seu valor é 7

pb.value = 10                       # que pode ser alterada no código
display(pb)	                        # exibe uma barra de progesso cheia

No exemplo seguinte fazemos uma interação entre os valores da barra de progresso com o clique de dois botões. O código usa o evento on_click dos botões para acionar as funções que aumentam e diminuem o valor da barra.

def aumentaBarra(s):
    pb.value +=1

def diminuiBarra(s):
    pb.value -=1

botaoMais = ipw.Button(description='Aumenta barra')
botaoMais.on_click(aumentaBarra)

botaoMenos = ipw.Button(description='Diminue barra')
botaoMenos.on_click(diminuiBarra)
# display(botaoMenos, botaoMais, pb)
# -- isso exibiria os controles um sobre o outro

# Para exibir os controles em uma linha única com título
# usamos HBox, Label

from ipywidgets import HBox, Label
HBox([Label('Em uma linha única:'), botaoMenos, botaoMais, pb])         # exibe figura (f)

Existem widgets mais sofisticados para formatação dos controles, inclusive com o uso de html e formatação css. Apenas para mostrar um exemplo segue o código abaixo, que usa HBox para construir uma linha e VBox para construir uma coluna de controles.

from ipywidgets import HBox, VBox, Label	
linha1 = HTML('<h2 style="color: red;">Use controles para modificar progress box</h2>')
linha2 = HBox([Label('Botões de controle:'), botaoMenos, botaoMais])
linha3 = pb
VBox([linha1, linha2, linha3]) # exibe figura (g)

Um clique no primeiro botão faz a barra de progressa avançar, no segundo faz a barra regredir.

Observe importamos os controles HBox,VBox e Label de ipywidget e, portanto eles podem ser usados diretamente sem menção à biblioteca de origem. Poderíamos usar a notação ipw.HBox para usar a caixa horizontal, sem precisar da importação explícita.

Outras informações sobre formatação dos widgets em
Layout and Styling of Jupyter widgets
.

Outros Widgets Úteis

HTMLMath serve para exibir equações matemáticas:

equacao = ipw.HTMLMath(
    value = r"Widgets podem ser usados para exibir equações inline \(x^2\) e destacadas $$\frac{x^2-1}{x-1}= x+1$$",
    placeholder='HTML',
    description='MathML:',
)
display(equacao)
MathML: Widgets podem ser usados para exibir equações inline \(x^2\) e destacadas $$\frac{x^2-1}{x-1}= x+1$$

ipyleaflet é uma biblioteca para a criação de mapas interativos que permitem marcação, arraste e ampliação. Em muitos casos, para executar um biblioteca recém instalada, pode ser necessário reinicializar o kernel.

# A biblioteca pode ser instalada com condas:
conda install -c conda-forge ipyleaflet

from ipyleaflet import Map
# inserindo as coordenadas da Praça da Liberdade em Belo Horizonte, MG
Map(center=[-19.932252,-43.9381638], zoom=15)

BeakerX é um pacote com widgets destinados a representar tabelas, gráficos, formulários de modo interativo. O widget de tabela reconhece e exibe dataframes do pandas. Ele facilita a pesquisa, e permite classificar, arrastar, filtrar, formatar ou selecionar células na tabela. Ele também permite a exportação para CSV ou área de transferência e a representação gráfica dos dados. O widget de tabela é mostrado abaixo, em imagem estática. Mais informações em Beakerx.

# Instalação do pacote
conda install -c conda-forge beakerx ipywidgets

import pandas as pd
from beakerx import *
pd.read_csv("UScity.csv")
# Instalando o pacote
conda install -c conda-forge k3d	

import k3d
plot = k3d.plot()
plot += k3d.points([0, 0, 0, 1, 1, 1])
plot.display()

A figura dentro do Notebook é dinâmica, podendo ser girada, ampliada, exportada, etc.

Modificando o estilo do Notebook

Jupyter Notebooks são enviados para o navegador como páginas html e são formatadas e estilizadas por meio de arquivos css (cascade style sheets) padrões. Para quem conhece html e css pode ser interessante editar diretamente esse arquivo. (Não se esqueça de fazer cópias de segurança dos arquivos que vai modificar).

Se sua instalação não contém a pasta “.jupyter” execute o comando jupyter notebook --generate-config no terminal. No Linux o arquivo de estilos está em /home/usuario/.jupyter/custom/custom.css, no Windows em pasta.do.python\Lib\site-packages\notebook\static\custom\custom.css, embora isso possa ser alterado ou ser diferente para outras instalações. Para ver a pasta onde está o arquivo de configurações você pode usar:

import jupyter_core
jupyter_core.paths.jupyter_config_dir()

Existem muitas folhas de estilo prontas para baixar, por exemplo no GitHub. Elas podem ser baixadas e copiadas para a pasta citada.

Para modificar apenas o estilo do Notebook aberto, sem alterar a aparência dos demais você pode usar:

# Importe biblioteca 
from IPython.core.display import HTML
HTML("<style> instruções de estilo </style>")
# Alternativamente se pode usar "mágica" em uma célula
%%html "<style> estilos - CSS </style>"

# Por exemplo, para atribuir margens laterais de 10% do tamanho da página use
display(HTML("<style>.container { margin: 0 10% 0 10% !important; }<style>"))

# Para exibir outputs em negrito
display(HTML("<style>.output_wrapper { font-weight: bold !important; }</style>"))

De dentro de um Notebook você pode carregar uma folha de estilo particular que passa a valer para aquele documento. Esse método é útil para formatar documentos de um tipo específico, por exemplo para uma apresentação ou páginas com estilos incomuns.

from IPython.core.display import HTML
def css_styling():
    styles = open("../styles/custom.css", "r").read()
    return HTML(styles)
css_styling()

Finalmente você pode instalar extensões tais como Jupyter themes.

Exportando e Compartilhando Notebooks


Notebooks podem ser exportados para diversos formatos tais como HTML e PDF e vários outros formatos. Isso pode ser encontrado no menu File | Download as. Se estiver trabalhando na nuvem a importação no formato nativo .ipynb serve para baixar para seu computador uma cópia do notebook. Ao subir uma cópia para o GitHub ou para o Colab você pode disponibilizar a sessão para outros colaboradores. Slides são úteis para aulas e apresentações.

NBViewer: NBViewer é um renderizador de notebooks, útil para quem quer ver uma sessão sem ter que necessariamente instalar o Jupyter. Esse é um serviço gratuito oferecido pelo Projeto Jupyter, disponível em nbviewer.jupyter.org. Ele recebe uma URL do notebook e o renderiza como página da web.

Bibliografia

  • Wintjen, Marc: Practical Data Analysis Using Jupyter Notebook: Learn how to speak the language of data by extracting useful and actionable insights using Python, Packt Publishing, Birmingham, UK, 2020.
  • Taieb, David: Thoughtful Data Science, , Packt Publishing, Birmingham, UK, 2018.
  • Dataquest: Advanced Jupyter Notebooks Tutorial, acessado em novembro de 2020.
  • Real Python: Jupyter Notebook Introduction, acessado em novembro de 2020.
  • Jupyter.org: Jupyter Main Site, acessado em novembro de 2020.
  • jupyter.org: Jupyter Widgets, acessado em novembro de 2020.

Marcação de Texto com Markdown

O que é Markdown

Markdown é uma linguagem de marcação de texto. Ele permite a insercão de códigos em ASCII que são renderizados em formatos mais sofisticados. Além disso ela permite a conversão para textos em HTML, que podem ser distribuídos pela web (ou localmente) e lidos por browsers. A marcação foi concebida para deixar o texto simples e legível. Markdown é software livre, disponível sob uma licença BSD de código aberto.

Títulos (Headings)

Para criar títulos use sinais # em frente ao texto (um para cada nível).

Markdown html Output obtido
# Título de nível 1
<h1>Título de nível 1</h1>
(título de nível 1)
## Título de nível 2
<h2>Título de nível 2</h2>
(título de nível 2)
### Título de nível 3
<h3>Título de nível 3</h3>
(título de nível 3)
#### Título de nível 4
<h4>Título de nível 4</h4>
(título de nível 4)
##### Título de nível 5
<h5>Título de nível 5</h5>
(título de nível 5)
###### Título de nível 6
<h6>Título de nível 6</h6>
(título de nível 6)
Parágrafos

Parágrafos são linhas de texto separadas por linhas vazias.

Markdown html Output obtido

Markdown é simples.

Vou usá-lo sempre!

<p>Markdown é simples.</p>
<p>Vou usá-lo sempre!</p>
Markdown é simples.

Vou usá-lo sempre!

Quebra de linhas

Para quebrar uma linha termine a linha com 2 ou mais espaços (⎵ ⎵) seguidos de return ().

Markdown html Output obtido
Essa é a primeira linha. ⎵⎵↲
Essa é a segunda linha.
<p>Essa é a primeira linha.<br>
Essa é a segunda linha.</p>
Essa é a primeira linha.
Essa é a segunda linha.
Negrito e itálico

Texto em negrito é obtido com asteriscos ou traços baixos (underscores) envolvendo o texto a negritar. Letras dentro da palavra também podem ser negritadas com duplos asteriscos.

Markdown html Output obtido
Precisamos de **negrito**.
Precisamos de <strong>negrito</strong>.
Precisamos de negrito.
Precisamos de __negrito__.
Precisamos de <b>negrito</b>.
Precisamos de negrito.
abcdef**GH**ij
abcdef<strong>GH</strong>ij
abdcefGHij

Textos em itálico são obtidos com um asterisco ou uma traço baixo (underscores) envolvendo o texto. Letras dentro da palavra também podem ser tornadas itálicos com um asterisco.

Markdown html Output obtido
Texto *em itálico*.
Texto <em>em itálico</em>.
Texto em itálico.
Texto _em itálico_.
Texto <i>em itálico</i>.
Texto em itálico.
a*bcd*ef
a<em>bcd</em>ef
abcdef

Texto em negrito e itálico simultâneos são obtidos com três asteriscos ou traços baixos (underscores) envolvendo o texto. Letras dentro da palavra também podem ser negritadas com três asteriscos.

Markdown html Output obtido
Um texto ***muito importante***.
Um texto <strong><em>muito importante</em></strong>.
Um texto muito importante.
Um texto ___muito importante___.
Um texto <b><i>muito importante</i></b>.
Um texto muito importante.
Um texto __*muito importante*__.
Um texto <i><b>muito importante</b></i>.
Um texto muito importante.
Um texto **_muito importante_**.
…idem…
Um texto muito importante.
Texto***muito***importante.
Texto<strong><em>muito</em></strong>importante.
Textomuitoimportante.

Textos riscados são obtidos com dois “tils” ˜˜ anterior e posterior ao texto.

Markdown html Output obtido
Texto ˜˜riscado˜˜.
Texto <del>riscado</del>.
Texto riscado.

Para criar blocos destacados (citações) coloque > na frente do parágrafo.

> “O poeta é um fingidor. Finge tão completamente que chega a fingir que é dor a dor que deveras sente.”
> ― Fernando Pessoa, Autopsicografia.

“O poeta é um fingidor. Finge tão completamente que chega a fingir que é dor a dor que deveras sente.”
― Fernando Pessoa, Autopsicografia.

Blocos destacados podem conter muitos parágrafos. Para isso basta inserir > em cada linha branca entre as parágrafos.

> “Nós, os mortais, alcançamos a imortalidade nas coisas que criamos em comum e que estão atrás de nós.”
>
> “A coisa mais bela que podemos experimentar é o mistério. Essa é a fonte de toda a arte e ciências verdadeiras.”
> ― Albert Einstein.

“Nós, os mortais, alcançamos a imortalidade nas coisas que criamos em comum e que estão atrás de nós.”
“A coisa mais bela que podemos experimentar é o mistério. Essa é a fonte de toda a arte e ciências verdadeiras”.
― Albert Einstein.

Blocos ou citações podem ser aninhadas. Para isso coloque >> na frente do parágrafo com segunda indentação.

> “Eu jamais iria para a fogueira por uma opinião minha pois não tenho certeza alguma. Porém, eu iria pelo
direito de ter e mudar de opinião, quantas vezes quisesse.”
>
>> ”Sem música a vida seria um erro.”
> ― Friedrich Nietzsche

“Eu jamais iria para a fogueira por uma opinião minha pois não tenho certeza alguma. Porém, eu iria pelo direito de ter e mudar de opinião, quantas vezes quisesse.”

“Sem música a vida seria um erro.”

― Friedrich Nietzsche

Listas

Listas ordenadas são criadas numerando-se as linhas, cada número seguido de ponto. Qualquer número serve para isso:

Markdown html Output obtido
1. Primeiro item
2. Segundo item
3. Terceiro item
4. Quarto item
<ol>
<li>Primeiro item</li>
<li>Segundo item</li>
<li>Terceiro item</li>
<li>Quarto item</li>
</ol>
  1. Primeiro item
  2. Segundo item
  3. Terceiro item
  4. Quarto item
1. Primeiro item
1. Segundo item
1. Terceiro item
1. Indentado item
1. Indentado item
1. Quarto item
<ol>
<li>Primeiro item</li>
<li>Segundo item</li>
<li>Terceiro item
<ol>
<li>Indentado item</li>
<li>Indentado item</li>
</ol>
</li>
<li>Quarto item</li>
</ol>
  1. Primeiro item
  2. Segundo item
  3. Terceiro item
    1. Indentado item
    2. Indentado item
  4. Quarto item

Observe que não é necessário usar a numeração correta nas listas. Alguns editores completam automaticamente esses números.

Listas não numeradas são criadas com os sinais *, + ou - antes dos itens.

Markdown html Output obtido
– Primeiro item
– Segundo item
– Terceiro item
– Quarto item
<ul>
<li>Primeiro item</li>
<li>Segundo item</li>
<li>Terceiro item</li>
<li>Quarto item</li>
</ul>
  • Primeiro item
  • Segundo item
  • Terceiro item
  • Quarto item
– Primeiro item
– Segundo item
– Terceiro item
– Indentado item
– Indentado item
– Quarto item
<ul>
<li>Primeiro item</li>
<li>Segundo item</li>
<li>Terceiro item
<ul>
<li>Indentado item</li>
<li>Indentado item</li>
</ul>
</li>
<li>Quarto item</li>
</ul>
  • Primeiro item
  • Segundo item
  • Terceiro item
    • Indentado item
    • Indentado item
  • Quarto item
Blocos de código

Uma anotação apropriada para código, principalmente de programação, é uma característica muito útil no markdown. A indentação correta para blocos de código pode ser conseguida com linhas precedidas por 4 espaços (⎵) ou 1 tab. Dentro de uma lista essas linhas são precedidas por 8 espaços ou 2 tabs. No exemplo abaixo usamos ⎵ como marcação para espaços:

Markdown html Output obtido
⎵⎵⎵⎵def soma(a,b):
⎵⎵⎵⎵⎵⎵⎵⎵return a + b
⎵⎵⎵⎵print (soma(5, 7))
<pre>
def soma(a,b):
return a + b
print (soma(5, 7))
</pre>
def soma(a,b):
return a + b
print (soma(5, 7))

Alternativamente, blocos de código também podem ser colocados entre três acentos graves, backticks, ```:

Markdown Output obtido
```
function factorial(n) {
if (n === 0) return 1; // 0! = 1
return n * factorial(n – 1);
}
factorial(3); // returns 6}
```
function factorial(n) {
if (n === 0) return 1; // 0! = 1
return n * factorial(n – 1);
}
factorial(3); // returns 6}

Nesse formato de bloco de código é possível marcar o código com cores, de acordo com a linguagem selecionada (syntax highlighting). Essa caracterí́stica depende do processador usado. No exemplo seguinte o código é marcado como JSON, o que é informado após o primeiro grupo de acentos graves.

Markdown Output obtido
``` json
{
“nome”: “José”,
“sobrenome”: “Garcia”,
“idade”: 45
}
```
{
  “nome”: “José”,
  “sobrenome”: “Garcia”,
  “idade”: 45
}

Para denotar texto em código, uma ou mais palavras, coloque-as entre acentos graves (backticks, `).

Markdown html Output obtido
Digite no prompt de comando: `nano`.
Digite no prompt de comando: <code>nano</code>.
Digite no prompt de comando: nano.
Imagens

Para acrescentar uma imagem use a seguinte sintaxe:

![Imagem 1](caminho/images/tux.png “Título a ser exibido”)

Tabelas

Tabelas são criadas usando-se a barra vertical | e hífens. Por exemplo, as três tabelas abaixo mostram o uso do código markdown.

Tabela (1)
| Título 1 | Título 2 | T3 |
| ‐‐‐‐‐‐‐‐‐‐‐‐| ‐‐‐‐‐‐‐‐‐‐‐‐| ‐‐‐|
| célula 1, 1 | célula 1, 2 | 1 |
| célula 2, 1 | célula 2, 2 | 2 |Tabela (2)| Alinhamento | Alinhamento | Alinhamento |
| :— | :—: | —: |
| Esquerda | Centro | Direita |
| 1 | 2 | 3 |

Tabela (3)

Título | N
-|-
a|b

renderizam as tabelas (1), (2) e (3) abaixo:

A tabela (2) ilustra o uso dos sinais de alinhamento: :– (à esquerda), :–: (centralizado) e –: (à direita). Os itens da tabela não precisam estar bem alinhados no markdown e as barras laterais são dispensáveis, como é mostrado na tabela (3). Dentro das tabelas o texto pode conter links, negrito e itálico e código.

Linha horizontal

Linhas horizontais são inseridas com três ou mais asteriscos (***), ‘dashes’ (---), ou ‘underscores’ (___) em uma linha.

Markdown html Output obtido
***
<hr>

Links

Links para outras páginas, locais ou na web, podem ser inseridos dentro de colchetes (ex.: [Duck Duck Go]) seguidos da URL entre parênteses. Por ex. (https://duckduckgo.com)).

Markdown html Output obtido
Recomendo o mecanismo de busca_ _
Duck Duck Go](https://duckduckgo.com).
Recomendo o mecanismo de busca <br>
<a href=”https://duckduckgo.com”>Duck Duck Go</a>.
Recomendo o mecanismo de busca
Duck Duck Go.
Notas de Pés de Página

Segue um exemplo de texto com notas de pé de página.

Use a seguinte notação para criar pés de página[^1], que também pode conter textos mais longos e várias parágrafos[^2].
Os marcadores não precisam ser números[^t].[^1]: O pé de página fica no final do texto.
[^2]: Um pé de página pode ter vários parágrafos.
Todos os parágrafos dentro da mesma nota devem ser indentados.
`{ function teste(a, b): # pode conter código e outras formatações. }`
[^t]: Outro pé de página.

Esse código é renderizado da seguinte forma (com os links efetivos):

Use a seguinte notação para criar pés de página[1], que também pode conter textos mais longos e várias parágrafos[2].
Os marcadores não precisam ser números[3].



1. O pé de página fica no final do texto.
2. Um pé de página pode ter vários parágrafos.
Todo o texto dentro do mesma anotação deve ser indentado.
{ function teste(a, b): # pode conter código e outras formatações. }
3. Outro pé de página.
Lista de tarefas

O código abaixo gera a lista mostrada à direita.

## Lista de Tarefas
– [x] Tarefa primeira (completa)
– [ ] Tarefa segunda
– [ ] Arranjar outras **tarefas**

Lista de Tarefas
☑ Tarefa primeira (completa)
Tarefa segunda
Arranjar outras tarefas

html

Vários dos aplicativos que usam Markdown, entre eles o Jupyter Notebook, podem renderizar corretamente diversas tags de marcação html. Isso é útil para usuários familiarizados com html, principalmente quando se pretende inserir texto com formatos mais sofisticados, tais como como texto colorido, com variação de tamanho, caixas coloridas, etc.

Como exemplo, o código à esquerda produzirá a barra vermelha à direita, útil para marcar o ponto de parada dentro de um notebook.

parei aqui ↷
<div style=”border:1px solid black;
padding:10px; color:white; background-color:red;”>
parei aqui &curarr;
</div>

Outro exemplo consiste na produção de texto sublinhado. Como não há código markdown específico para isso você pode conseguir texto sublinhado com as tags:

Texto 1 sublinhado ou Texto 2 sublinhado
<u>Texto 1 sublinhado</u> ou <ins>Texto 2 sublinhado</ins>
Latex

LaTeX é uma linguagem de composição de texto para a produção de documentos científicos. Vários editores de Markdown podem renderizar equações matemáticas e símbolos Latex para reproduzir notação matemática. Em particular o Jupyter Notebook reconhece código LaTeX escrito nas células de Markdown e os renderiza corretamente no navegador usando a biblioteca JavaScript MathJax. Para inserir uma fórmula matemática em uma linha use o símbolo $expressão$. Para equações isoladas em uma linha e centralizadas use $$expressão$$.

A identidade de Euler é $e^{i \pi} + 1 = 0$.
As equações de Einstein são:
$$
R_{\mu\nu}-\frac{1}{2} Rg_{\mu\nu} +\Lambda g_{\mu\nu} = \frac{8 \pi G}{c^4} T_{\mu\nu}.
$$
A definição da derivada de primeira ordem é:
$$
f'(x) = \lim\limits_{h \rightarrow 0} \frac{f(x+h) – f(x)}{h}
$$

A identidade de Euler é \(e^{i \pi} + 1 = 0\).
As equações de Einstein são:
$$
R_{\mu\nu}-\frac{1}{2} Rg_{\mu\nu} +\Lambda g_{\mu\nu} = \frac{8 \pi G}{c^4} T_{\mu\nu}.
$$
A definição da derivada de primeira ordem é:
$$
f'(x) = \lim\limits_{h \rightarrow 0} \frac{f(x+h) – f(x)}{h}
$$

Bibliografia

Análise Fatorial Usando Python

Nossa análise de fatores será feita com o módulo factor_analyser do Python. Os dados usados são originados do Synthetic Aperture Personality Assessment (SAPA) que contém 25 questões de auto-avaliação pessoais disponíveis na web na página de Vincent Arel-Bundock, no Github. Os dados foram colhidos de 2800 sujeitos com 3 campos adicionais de dados demográficos: sexo, educação e idade. Esses dados estão sob o formato *.csv (valores separados por vírgula) e foram salvos na pasta do projeto, ./dbs.

Dados do bfi

A1: Sou indiferente aos sentimentos das outras pessoas.
A2: Sempre pergunto sobre o bem-estar dos outros.
A3: Sei como confortar os outros.
A4: Adoro crianças.
A5: Faço as pessoas se sentirem à vontade.
C1: Sou exigente no meu trabalho.
C2: Continuo minhas tarefas até que tudo esteja perfeito.
C3: Faço as coisas de acordo com um plano.
C4: Deixo tarefas semi-acabadas.
C5: Desperdiço meu tempo.
E1: Não falo muito.
E2: Tenho dificuldades para abordar outras pessoas.
E3: Sei como cativar as pessoas.
E4: Faço amigos facilmente.
E5: Assumo o controle das situações.
N1: Fico com raiva facilmente.
N2: Irrito-me facilmente.
N3: Tenho alterações de humor frequentes. (q_1099
N4: Muitas vezes me sinto triste.
N5: Entro em pânico facilmente.
O1: Sempre tenho muitas ideias.
O2: Evito leituras complexas.
O3: Procuro levar as conversas para um nível elevado.
O4: Passo algum tempo refletindo sobre as coisas.
O5: Nunca me detenho a avaliar um assunto profundamente.
Os itens estão organizados por fatores esperados (a serem verificados pela análise): Agreeableness, Conscientiousness, Extroversion, Neuroticism e Opennness. [Respectivamente: Amabilidade, Consienciosidade, Extroversão, Neurotismo, Abertura.]As questões demográficas estão codificadas da seguinte forma:
Gênero: Masculino = 1, Feminino = 2
Educação:

  1. Nível médio incompleto,
  2. Nível médio completo,
  3. Nível superior incompleto,
  4. Nível superior completo,
  5. pós-graduado.

Idade: a idade (em anos).

Os dados foram coletados em uma escala de resposta:

  1. Totalmente falso,
  2. Moderadamente falso,
  3. Um pouco falso,
  4. Um pouco correto,
  5. Moderadamente correto,
  6. Totalmente correto.

Interface de Jupyter Notebook, rodando Python 3
Jupyter Notebook e convenções usadas

Jupyter Notebook é uma aplicação web opensource que permite sessões colaborativas e documentos compartilhados contendo código que pode ser executado dentro da página, equações bem formatadas, visualização gráfica e texto narrativo que podem ser postas sob forma de apresentações ou usadas para desenvolvimento. Seu uso inclui tratamento, transformação e visualização de dados, simulações numéricas, modelagem estatística, machine learning entre outras aplicações. Maiores informações e instaladores em Jupyter.org.

# O projeto será rodado em uma sessão do Jupyter Notebook.
# Linhas iniciadas por '#' são comentários.
# As células de código do Jupyter Notebook aparecem dessa forma: Ex.:
print('Outputs do Jupyter Notebook, gráficos e dataframes exibidos aparecem como nesse quadro...')
# Em casos de outputs simples e compactos eles podem aparecer como um comentário após o comando:
print('output simples')    # Esse comando imprime 'output simples'
Outputs do Jupyter Notebook, gráficos e dataframes exibidos aparecem como nesse quadro…

Tratamento dos dados do bsi por meio do factor_analyser

# Instalação do módulo factor_analyzer dentro do ambiente Jupyter:
conda install -c ets factor_analyzer

# Importando bibliotecas (libraries) necessárias
import pandas as pd
import numpy as np
from factor_analyzer import FactorAnalyzer
import matplotlib.pyplot as plt

# A leitura do arquivo de dados para dentro de um dataframe (do pandas)
df = pd.read_csv('./dbs/bfi.csv')

# Renomear a primeira coluna (que está sem nome) para 'id'
df.rename(columns = {'Unnamed: 0':'id'}, inplace = True) 
print('A tabela importada contém %d linhas, %d colunas' % df.shape)
print('contendo as seguintes colunas:\n', df.columns)

# Para visualizar a tabela importada:
df.head()
A tabela importada contém 2800 linhas, 29 colunas
contendo as seguintes colunas:
Index([‘id’, ‘A1’, ‘A2’, ‘A3’, ‘A4’, ‘A5’, ‘C1’, ‘C2’, ‘C3’, ‘C4’, ‘C5’, ‘E1’,
‘E2’, ‘E3’, ‘E4’, ‘E5’, ‘N1’, ‘N2’, ‘N3’, ‘N4’, ‘N5’, ‘O1’, ‘O2’, ‘O3’,
‘O4’, ‘O5’, ‘gender’, ‘education’, ‘age’],
dtype=’object’)

id A1 A2 A3 A4 A5 C1 C2 C3 C4 N4 N5 O1 O2 O3 O4 O5 gender education age
0 61617 2.0 4.0 3.0 4.0 4.0 2.0 3.0 3.0 4.0 2.0 3.0 3.0 6 3.0 4.0 3.0 1 NaN 16
1 61618 2.0 4.0 5.0 2.0 5.0 5.0 4.0 4.0 3.0 5.0 5.0 4.0 2 4.0 3.0 3.0 2 NaN 18
2 61620 5.0 4.0 5.0 4.0 4.0 4.0 5.0 4.0 2.0 2.0 3.0 4.0 2 5.0 5.0 2.0 2 NaN 17
3 61621 4.0 4.0 6.0 5.0 5.0 4.0 4.0 3.0 5.0 4.0 1.0 3.0 3 4.0 3.0 5.0 2 NaN 17
4 61622 2.0 3.0 3.0 4.0 5.0 4.0 4.0 5.0 3.0 4.0 3.0 3.0 3 4.0 3.0 3.0 1 NaN 17

2800 rows × 29 columns

Como em qualquer outro uso de dados, principalmente quando importados de fontes externas, fazemos uma verificação de estrutura e completeza, presença de valores ausentes (NaN). Os dados demográficos são armazendos em outro dataframe enquanto a avaliação das questões em si são deixadas no dataframe df depois de eliminados os campos relativos a dados demográficos.

# Tabela dfDemografico armazena id, sexo, educação e idade
dfDemografico = df[['id', 'gender', 'education', 'age']]

# Colunas desnecessárias são eliminadas de df
df.drop(['id', 'gender', 'education', 'age'],axis=1,inplace=True)

# Possíveis dados ausentes são eliminados
df.dropna(inplace=True)

# Para verificar as colunas de df
df.head(2)
A1 A2 A3 A4 A5 C1 C2 C3 C4 C5 N1 N2 N3 N4 N5 O1 O2 O3 O4 O5
0 2.0 4.0 3.0 4.0 4.0 2.0 3.0 3.0 4.0 4.0 3.0 4.0 2.0 2.0 3.0 3.0 6 3.0 4.0 3.0
1 2.0 4.0 5.0 2.0 5.0 5.0 4.0 4.0 3.0 4.0 3.0 3.0 3.0 5.0 5.0 4.0 2 4.0 3.0 3.0

2 rows × 25 columns

# Uma visão geral dos dados no dataframe df pode ser vista:
df.info()
<class ‘pandas.core.frame.DataFrame’>
Int64Index: 2436 entries, 0 to 2799
Data columns (total 25 columns):
# Column Non-Null Count Dtype
—————————————————————————————
0 A1 2436 non-null float64
1 A2 2436 non-null float64
2 A3 2436 non-null float64
3 A4 2436 non-null float64
4 A5 2436 non-null float64
Grupos C, E, N omitidos
20 O1 2436 non-null float64
21 O2 2436 non-null int64
22 O3 2436 non-null float64
23 O4 2436 non-null float64
24 O5 2436 non-null float64
dtypes: float64(24), int64(1)
memory usage: 494.8 KB

Observamos que apenas o campo O2 tem tipo de variável int64. Apenas para ter todos os campos do mesmo tipo fazemos a conversão para float64.

# Converter o campo O2 em float
df['O2'] = df['O2'].astype(np.float64)

type(df['O2'][0])    # Agora o campo é do tipo numpy.float64

Estamos prontos para encontrar a matriz de correlação entre as variáveis. Cada célula dessa matriz mostra a correlação entre duas variáveis, listadas como labels das linhas e colunas. Por isso ele tem os valores da diagonal iguais a 1 (que é a correlação da variável consigo mesma). A matriz de correlação fornece uma visão geral de interrelacionamento dos dados e é usada como input para análises mais advançadas. A correlação .corr é um método de dataframes do pandas.

# A matriz de correlação entre todas as respostas na tabela
corrMatriz = df.corr()

# Para ver apenas as correlações entre variáveis do grupo A
corrMatriz[["A1", "A2","A3", "A4","A5"]].head(5)
A1 A2 A3 A4 A5
A1 1.000000 -0.350905 -0.273636 -0.156754 -0.192698
A2 -0.350905 1.000000 0.503041 0.350856 0.397400
A3 -0.273636 0.503041 1.000000 0.384918 0.515679
A4 -0.156754 0.350856 0.384918 1.000000 0.325644
A5 -0.192698 0.397400 0.515679 0.325644 1.000000

Em seguida fazemos o gráfico de calor (heatmap) da matriz de correlação. Usamos a biblioteca seaborn para isso. Um heatmap associa uma cor a cada valor na matriz de correção. Tons mais escuros de azul (nesse caso) são valores mais perto de 1, tons mais claros são valores mais perto de -1.

import seaborn as sns
plt.figure(figsize=(12,12))
sns.set(font_scale=1)
sns.heatmap(corrMatriz, linewidths=.1, linecolor='#ffffff',
            cmap='YlGnBu', xticklabels=1, yticklabels=1)

A mera análise do gráfico de calor permite que algumas características da pesquisa sejam visualmente reconhecidas. Duas variáveis separadas com índice de correlação muito alto podem ser, na verdade, a mesma variável escrita ou ordenada de forma diversa. Nesse caso o pesquisador pode preferir retirar uma delas. Uma ou mais variáveis com nível de correlação muito baixo com todas as demais podem indicar a medida de elementos isolados e fora de contexto com o modelo explorado. Nesse caso vemos agrupamentos claros entre as variáveis A2, A3, A4, A5, e todas as do grupo N, só para citar alguns exemplos.

Análise Fatorial

Análise Fatorial Exploratória, AFE

Podemos agora dar início ao uso específico da Análise Fatorial, começando pela Análise Fatorial Exploratória, AFE, usando o módulo factor_analyzer. O primeiro passo para isso é a avaliação da fatorabilidade dos dados. Isso significa que os dados coletados podem ser agrupados em fatores, que são as nossas variáveis ocultas com o poder de sintetizar e melhor descrever o objeto estudado. Para isso o módulo factor_analyzer oferece dois testes: o Teste de Bartlett e o Teste de Kaiser-Meyer-Olkin.

O Teste da esfericidade de Bartlett verifica se as variáveis estão correlacionadas entre si, comparando a matriz de correlação com a matriz identidade (que representaria variáveis completamente não correlacionadas).

# Importa o módulo que realiza o teste de Bartlett
from factor_analyzer.factor_analyzer import calculate_bartlett_sphericity
print('Teste da Esfericidade de Bartlett: chi² = %d,  p_value = %d' % (chi_square_value, p_value))
Teste da Esfericidade de Bartlett: chi² = 18170.966350869272 p_value = 0.

No nosso caso o teste de Bartlett resulta em p-value = 0, o que indica que os dados podem ser fatorados e a matriz de correlação observada não é a identidade.

O Teste de Kaiser-Meyer-Olkin (KMO) também mede se os dados colhidos são apropriados para esta análise fatorial. Ele realiza um teste para cada variável observada e para o conjunto completo de variáveis. KMO é uma estimativa da proporção de variância entre todas as variáveis. Proporções mais baixas são mais adequadas para essa abordagem. Os valores de KMO podem estar entre 0 e 1. Valores de KMO abaixo de 0.6 são consideredos inadequados.

# Importa calculate_kmo
from factor_analyzer.factor_analyzer import calculate_kmo
kmo_all,kmo_model = calculate_kmo(df)

print('Valores de kmo_all =\n', kmo_all, '\n\n')
print('KMO =', kmo_model)
Valores de kmo_all =
[0.75391928 0.8363196 0.87010963 0.87795367 0.90348747 0.84325413
0.79568263 0.85186857 0.82647206 0.86401687 0.83801873 0.88380544
0.89697008 0.87731273 0.89332158 0.77933902 0.78025018 0.86229919
0.88518467 0.86014155 0.85858672 0.78019798 0.84434957 0.77003158
0.76144469]

KMO = 0.848539722194922

Todos os valores de kmo_all são superiores a 0,7 e o KMO geral é KMO = 0.8485 o que são considerados valores muito favoráveis para a análise dos fatores.

Prosseguimos criando uma instância do objeto factor_analysis, tentativamente com 5 fatores

# Criamos objeto factor_analysis, sem rotação e usando 5 fatores (tentativamente)
fa = FactorAnalyzer(5, rotation=None)
# Aplicmos nele o método fit (ajuste)
fa.fit(df)
# O ajuste resulta nos autovalores
ev, v = fa.get_eigenvalues()
print('São ' + str(len(ev)) + ' autovalores:\n', ev)
São 25 eigenvalues:
[5.13431118 2.75188667 2.14270195 1.85232761 1.54816285 1.07358247
0.83953893 0.79920618 0.71898919 0.68808879 0.67637336 0.65179984
0.62325295 0.59656284 0.56309083 0.54330533 0.51451752 0.49450315
0.48263952 0.448921 0.42336611 0.40067145 0.38780448 0.38185679
0.26253902]
from bokeh.plotting import figure, output_notebook, show
output_notebook()

eixoX = range(1, len(ev)+1)   # de 1 0 26
eixoY = ev
p = figure(title='Scree Plot', x_axis_label='n-ésimo autovalor',y_axis_label='autovalor', 
           x_range=[0,25], y_range=(0, 6), plot_width=400, plot_height=400,
           background_fill_color='#f1f1fa')

p.circle(eixoX, eixoY, size=6, fill_color='red', color='black')
p.line(eixoX, eixoY, line_width=1, color = '#afafaf')
show(p)


 
Usando os autovalores calculados traçamos um Screeplot que é um gráfico que lista os autovalores em ordem decrescente, usado para determinar o número de fatores a serem retidos em uma análise fatorial exploratória. O teste, introduzido por R.B. Cattell em 1966 sugere manter tantos fatores quantos forem as autovalores anteriores a uma “dobra mais acentuada” ou “cotovelo” no gráfico. Também é sugerido manter o mesmo número de fatores quantos autovalores existirem maiores que 1.

Algumas críticas são dirigidas ao teste feito dessa forma pois ele insere uma decisão pouco objetiva. Mais de um cotovelo podem aparecer no gráfico. De qualquer forma, como veremos no presente caso o bom senso e a análise posterior dos agrupamentos de fatores podem sugerir uma alteração nesse número.

Bibliografia

  • Goldberg, L. R. (1999). A broad-bandwidth, public domain, personality inventory measuring the lower-level facets of several five-factor models. In I. Mervielde, I. Deary, F. De Fruyt, & F. Ostendorf (Eds.), Personality Psychology in Europe, Vol. 7 (pp. 7-28). Tilburg, The Netherlands: Tilburg University Press.

Entidades HTML

Entidades HTML são códigos usados para a exibição de símbolos que não estão diretamente acessíveis pelo teclado, dentro de uma página de HTML (páginas da WEB). Eles podem representar caracteres técnicos, matemáticos, símbolos de moedas, sinais gráficos e muitos outros. A tabela lista os códigos html hexadecimal e decimal. Por exemplo, a página:

<html>
<body>
<h1>Exibindo html </h1>
<p>Símbolo de um naipe espada de baralho: &clubs; – &clubsuit; – &♣; – &#9827;.</p>
<p>Símbolo matemático da integral de contorno: &conint; – &oint; – &#x0222e; – &#8750;.
</body>
</html>

seria exibida da seguinte forma (dependendo, é claro, das instruções css da página:

Exibindo html

Símbolo de um naipe espada de baralho: ♣ – ♣ – ♣ – ♣.
Símbolo matemático, integral de contorno: ∮ – ∮ – ∮ – ∮.

Nem todos os browsers podem exibir corretamente todos os símbolos. Um código na primeira coluna da tabela representa uma falha de exibição. Passe o mouse sobre os caracteres da 1ª coluna para ampliar.

Caracteres comuns: Pontuação
Caracter HTML HEX DEC Descrição
" &quot; &#x00022; &#34; aspas
, &comma; &#x0002c; &#44; vírgula
. &period; &#x0002e; &#46; ponto final
: &colon; &#x0003a; &#58; dois pontos
; &semi; &#x0003b; &#59; ponto e vírgula
? &quest; &#x0003f; &#63; ponto de interrogação
¿ &iquest; &#x000bf; &#191; ponto de interrogação invertido
! &excl; &#x00021; &#33; ponto de exclamação
¡ &iexcl; &#x000a1; &#161; ponto de exclamação invertido
Barras e Aspas
Caracter HTML HEX DEC Descrição
&hyphen; &dash; &#x02010; &#8208; hífen
&ndash; &#x02013; &#8211; en dash
&mdash; &#x02014; &#8212; travessão
&horbar; &#x02015; &#8213; barra horizontal
| &verbar; &vert; &#x02016; &#8214; barra vertical
/ &sol; &#x0002f; &#47; barra, travessa ou tranca
\ &bsol; &#x0005c; &#92; barra reversa
_ &lowbar; &#x0005f; &#95; linha baixa
¦ &brvbar; &#x000a6; &#166; barra quebrada
&lsquo; &opencurlyquote; &#x02018; &#8216; aspas simples esquerda
&rsquo; &rsquor; &closecurlyquote; &#x02019; &#8217; aspas simples direitas
&lsquor; &sbquo; &#x0201a; &#8218; aspas baixas simples
&ldquo; &opencurlydoublequote; &#x0201c; &#8220; aspas duplas esquerdas
&rdquo; &rdquor; &closecurlydoublequote; &#x0201d; &#8221; aspas duplas direitas
&ldquor; &bdquo; &#x0201e; &#8222; aspas baixas duplas
« &laquo; &#x000ab; &#171; aspa dupla angular esquerda
» &raquo; &#x000bb; &#187; aspa dupla angular direita
Sinais Tipográficos
Caracter HTML HEX DEC Descrição
§ &sect; &#x000a7; &#167; seção (parágrafo)
&para; &#x000b6; &#182; marca de parágrafo, alínea
&blank; &#x02423; &#9251; caixa aberta
Abreviaturas
Caracter HTML HEX DEC Descrição
# &num; &#x00023; &#35; número
$ &dollar; &#x00024; &#36; cifrão
% &percnt; &#x00025; &#37; porcentagem
@ &commat; &#x00040; &#64; comercial em (arroba)
® &reg; &#x000ae; &#174; marca registrada
° &deg; &#x000b0; &#176; grau
¢ &cent; &#x000a2; &#162; 1 centésimo
¤ &curren; &#x000a4; &#164; moeda
&euro; &#x020ac; &#8364; sinal do euro
£ &pound; &#x000a3; &#163; libra
¥ &yen; &#x000a5; &#165; iene
& &amp; &#x00026; &#38; e comercial
* &ast; &midast; &#x0002a; &#42; asterisco
¬ &not; &#x000ac; &#172; negação (not)
­ &shy; &#x000ad; &#173; hífen suave
¯ &macr; &strns; &#x000af; &#175; mácron
· &middot; &#x000b7; &#183; ponto central
Espaçamento e controles
Caracter HTML HEX DEC Descrição
tab &tab; &#x00009; &#9; caracter de tabulação
newline &newline; &#x0000a; &#10; alimentação de linha (lf)
&nbsp; &nonbreakingspace; &#x000a0; &#160; espaço sem quebra | |
&ensp; &#x02002; &#8194; espaço | |
&emsp; &#x02003; &#8195; espaço | |
&emsp13; &#x02004; &#8196; espaço 1 terço | |
&emsp14; &#x02005; &#8197; espaço 1 quarto | |
&numsp; &#x02007; &#8199; espaço de figura | |
&puncsp; &#x02008; &#8200; espaço de pontuação | |
&thinsp; &thinspace; &#x02009; &#8201; espaço pequeno | |
&hairsp; &verythinspace; &#x0200a; &#8202; espaço muito pequeno | |
&zerowidthspace; &negativethickspace; &#x0200b; &#8203; espaço de largura zero |​|
&zwnj; &#x0200c; &#8204; largura zero não grudado |‌|
&zwj; &#x0200d; &#8205; largura zero grudado |‍|
&mediumspace; &#x0205f; &#8287; espaço matemático médio | |
&nobreak; &#x02060; &#8288; juntador de palavras
&invisibletimes; &it; &#x02062; &#8290; multiplicação invisível
&invisiblecomma; &ic; &#x02063; &#8291; vírgula invisível
&lrm; &#x0200e; &#8206; marca da esquerda para a direita
&rlm; &#x0200f; &#8207; marca da direita para a esquerda
&elinters; &#x023e7; &#9191; intersecção elétrica
Ícones, Símbolos
Caracter HTML HEX DEC Descrição
&starf; &bigstar; &#x02605; &#9733; estrela preta
&star; &#x02606; &#9734; estrela branca
&spades; &spadesuit; &#x02660; &#9824; naipe paus preto
&clubs; &clubsuit; &#x02663; &#9827; naipe espada preto
&hearts; &heartsuit; &#x02665; &#9829; naipe copa preto
&diams; &diamondsuit; &#x02666; &#9830; naipe ouro preto
&loz; &#9674; &#x25CA; losango branco
&sung; &#x0266a; &#9834; oitava nota
&flat; &#x0266d; &#9837; bemol musical
&natur; &natural; &#x0266e; &#9838; natural de música
&sharp; &#x0266f; &#9839; sharp, sustenido músical
&check; &checkmark; &#x02713; &#10003; marca de verificação
&cross; &#x02717; &#10007; seleção x
&malt; &maltese; &#x02720; &#10016; cruz maltesa
&sext; &#x02736; &#10038; estrela preta de seis pontas
&lozf; &blacklozenge; &#x029eb; &#10731; losango preto
© &copy; &#x000a9; &#169; direitos autorais
&os; &circleds; &#x024c8; &#9416; letra latina s maiúscula circulada
Símbolos Matemáticos: Operadores
Caracter HTML HEX DEC Descrição
+ &plus; &#x0002b; &#43; soma, mais
± &plusmn; &pm; &#x000b1; &#177; mais ou menos
× &times; &#x000d7; &#215; multiplicação
÷ &divide; &div; &#x000f7; &#247; divisão
= &equals; &#x0003d; &#61; igual
< &lt; &#x0003c; &#60; menor que
> &gt; &#x0003e; &#62; maior que
&minus; &#x02212; &#8722; menos (subtração)
&mnplus; &mp; &minusplus; &#x02213; &#8723; menos ou mais
&plusdo; &dotplus; &#x02214; &#8724; ponto mais
&radic; &sqrt; &#x0221a; &#8730; raiz quadrada
&setmn; &setminus; &ssetmn; &#x02216; &#8726; menos de conjunto
&lowast; &#x02217; &#8727; operador asterisco
&compfn; &smallcircle; &#x02218; &#8728; operador anel
&oplus; &circleplus; &#x02295; &#8853; mais circulado
&ominus; &circleminus; &#x02296; &#8854; menos circulado
&otimes; &circletimes; &#x02297; &#8855; vezes circulado
&osol; &#x02298; &#8856; divisão circulada
&odot; &circledot; &#x02299; &#8857; ponto circulado
&ocir; &circledcirc; &#x0229a; &#8858; operador de anel circular
&oast; &circledast; &#x0229b; &#8859; asterisco circulado
&odash; &circleddash; &#x0229d; &#8861; traço circulado
&plusb; &boxplus; &#x0229e; &#8862; mais quadrado
&minusb; &boxminus; &#x0229f; &#8863; menos quadrado
&timesb; &boxtimes; &#x022a0; &#8864; vezes quadrado
&sdotb; &dotsquare; &#x022a1; &#8865; ponto quadrado
&xodot; &bigodot; &#x02a00; &#10752; operador de ponto circulado n-ário
&xoplus; &bigoplus; &#x02a01; &#10753; operador n-áry com círculo plus
&xotime; &bigotimes; &#x02a02; &#10754; operador de tempos circulados n-ário
&xuplus; &biguplus; &#x02a04; &#10756; operador de união n-ária com mais
&xsqcup; &bigsqcup; &#x02a06; &#10758; operador de união quadrada n-ária
&forall; &#x02200; &#8704; para todos
&comp; &complement; &#x02201; &#8705; complemento
&part; &partiald; &#x02202; &#8706; diferencial parcial
&exist; &exists; &#x02203; &#8707; existe
&nexist; &nexists; &#x02204; &#8708; não existe
&empty; &emptyset; &emptyv; &#x02205; &#8709; conjunto vazio
&nabla; &del; &#x02207; &#8711; nabla
&isin; &isinv; &element; &in; &#x02208; &#8712; elemento de
&notin; &notelement; &notinva; &#x02209; &#8713; não é elemento de
&niv; &reverseelement; &ni; &suchthat; &#x0220b; &#8715; contém como membro
&notni; &notniva; &notreverseelement; &#x0220c; &#8716; não contém como membro
&prod; &product; &#x0220f; &#8719; produtória
&coprod; &coproduct; &#x02210; &#8720; coprodutório
&sum; &#x02211; &#8721; somatório
Operações e Relações em Conjuntos
Caracter HTML HEX DEC Descrição
&uplus; &unionplus; &#x0228e; &#8846; união de conjuntos
&xcap; &intersection; &bigcap; &#x022c2; &#8898; interseção de conjuntos
&xcup; &union; &bigcup; &#x022c3; &#8899; união de conjuntos
&sub; &subset; &#x02282; &#8834; subconjunto de
&sup; &supset; &superset; &#x02283; &#8835; superconjunto de
&nsub; &#x02284; &#8836; não é um subconjunto de
&nsup; &#x02285; &#8837; não um superconjunto de
&sube; &subsetequal; &subseteq; &#x02286; &#8838; subconjunto de ou igual a
&supe; &supseteq; &supersetequal; &#x02287; &#8839; superconjunto de ou igual a
&nsube; &nsubseteq; &notsubsetequal; &#x02288; &#8840; nem um subconjunto de nem igual a
&nsupe; &nsupseteq; &notsupersetequal; &#x02289; &#8841; nem um superconjunto de nem igual a
&subne; &subsetneq; &#x0228a; &#8842; subconjunto de com não igual a
&supne; &supsetneq; &#x0228b; &#8843; superconjunto de com não igual a
&cupdot; &#x0228d; &#8845; multiplicação de conjuntos
Caracteres Especiais
Caracter HTML HEX DEC Descrição
ı &imath; &inodot; &#x00131; &#305; i sem ponto (mat.)
ȷ &jmath; &#x00237; &#567; j sem ponto (mat)
ƒ &fnof; &#x00192; &#402; f cortado
¹ &sup1; &#x000b9; &#185; um sobrescrito
&iinfin; &#x029dc; &#10716; infinito incompleto
&infintie; &#x029dd; &#10717; ligadura sobre infinito
&nvinfin; &#x029de; &#10718; infinito negado com barra vertical
µ &micro; &#x000b5; &#181; micro
Frações
Caracter HTML HEX DEC Descrição
¼ &frac14; &#x000bc; &#188; fração um quarto
½ &frac12; &half; &#x000bd; &#189; fração metade
¾ &frac34; &#x000be; &#190; fração três quartos
&frac13; &#x02153; &#8531; fração um terço
&frac23; &#x02154; &#8532; fração dois terços
&frac15; &#x02155; &#8533; fração um quinto
&frac25; &#x02156; &#8534; fração dois quintos
&frac35; &#x02157; &#8535; fração três quintos
&frac45; &#x02158; &#8536; fração quatro quintos
&frac16; &#x02159; &#8537; fração um sexto
&frac56; &#x0215a; &#8538; fração cinco sextos
&frac18; &#x0215b; &#8539; fração um oitavo
&frac38; &#x0215c; &#8540; fração três oitavos
&frac58; &#x0215d; &#8541; fração cinco oitavos
&frac78; &#x0215e; &#8542; fração sete oitavos
Sobrescritos
Caracter HTML HEX DEC Descrição
² &sup2; &#x000b2; &#178; dois sobrescrito
³ &sup3; &#x000b3; &#179; três sobrescrito
ª &ordf; &#x000aa; &#170; ordinal feminino
º &ordm; &#x000ba; &#186; ordinal masculino
Delimitadores
Caracter HTML HEX DEC Descrição
( &lpar; &#x00028; &#40; parêntese esquerdo
) &rpar; &#x00029; &#41; parêntese direito
[ &lsqb; &lbrack; &#x0005b; &#91; colchete esquerdo
] &rsqb; &rbrack; &#x0005d; &#93; colchete direito
{ &lcub; &lbrace; &#x0007b; &#123; chave esquerda
} &rcub; &rbrace; &#x0007d; &#125; chave direita
| &verbar; &vert; &#x0007c; &#124; linha vertical
&lang; &leftanglebracket; &langle; &#x027e8; &#10216; colchete angular esquerdo
&rang; &rightanglebracket; &rangle; &#x027e9; &#10217; colchete angular direito
&lang; &#x027ea; &#10218; colchete angular esquerdo duplo
&rang; &#x027eb; &#10219; colchete angular direito duplo
&verticalseparator; &#x02758; &#10072; barra vertical leve
Delimitadores Decorativos
Caracter HTML HEX DEC Descrição
&lbbrk; &#x02772; &#10098; chave ornamental esquerda clara
&rbbrk; &#x02773; &#10099; chave ornamental direita clara
&lobrk; &leftdoublebracket; &#x027e6; &#10214; colchete branco esquerdo
&robrk; &rightdoublebracket; &#x027e7; &#10215; colchete branco direito
&loang; &#x027ec; &#10220; colchete branco esquerdo
&roang; &#x027ed; &#10221; colchete branco direito
&ufisht; &#x0297e; &#10622; rabo de peixe
⥿ &dfisht; &#x0297f; &#10623; cauda de peixe para baixo
&lopar; &#x02985; &#10629; parêntese branco esquerdo
&ropar; &#x02986; &#10630; parêntese branco direito
&lbrke; &#x0298b; &#10635; colchete esquerdo com barra inferior
&rbrke; &#x0298c; &#10636; colchete direito com barra inferior
&lbrkslu; &#x0298d; &#10637; colchete esquerdo com marca no canto superior
&rbrksld; &#x0298e; &#10638; colchete direito com marca no canto inferior
&lbrksld; &#x0298f; &#10639; colchete esquerdo com marca no canto inferior
&rbrkslu; &#x02990; &#10640; colchete direito com marca no canto superior
&langd; &#x02991; &#10641; colchete angular esquerdo com ponto
&rangd; &#x02992; &#10642; colchete angular direito com ponto
&lparlt; &#x02993; &#10643; arco esquerdo menor que colchete
&rpargt; &#x02994; &#10644; arco direito maior que colchete
&gtlpar; &#x02995; &#10645; arco esquerdo duplo maior que colchete
&ltrpar; &#x02996; &#10646; arco direito duplo menor que colchete
Integrais
Caracter HTML HEX DEC Descrição
&int; &integral; &#x0222b; &#8747; integral
&int; &#x0222c; &#8748; integral dupla
&tint; &iiint; &#x0222d; &#8749; integral triplo
&conint; &oint; &contourintegral; &#x0222e; &#8750; integral de contorno
&conint; &doublecontourintegral; &#x0222f; &#8751; integral de superfície
&cwint; &#x02231; &#8753; integral no sentido horário
&awint; &#x02a11; &#10769; integração anti-horário
&cwconint; &#x02232; &#8754; integral de contorno no sentido horário
&awconint; &#x02233; &#8755; integral de contorno anti-horário
&qint; &iiiint; &#x02a0c; &#10764; operador quádruplo integral
&fpartint; &#x02a0d; &#10765; parte finita integral
&cirfnint; &#x02a10; &#10768; função de circulação
&rppolint; &#x02a12; &#10770; integral com caminho retangular em torno do pólo
&scpolint; &#x02a13; &#10771; integral com caminho semicircular em torno do pólo
&npolint; &#x02a14; &#10772; integração de linha não incluindo o pólo
&pointint; &#x02a15; &#10773; integral em torno de um operador de ponto
&quatint; &#x02a16; &#10774; operador integral de quatérnio
&intlarhk; &#x02a17; &#10775; integral com seta esquerda com gancho
Setas
Caracter HTML HEX DEC Descrição
&larr; &leftarrow; &leftarrow; &slarr; &#x02190; &#8592; seta esquerda
&uarr; &uparrow; &uparrow; &shortuparrow; &#x02191; &#8593; seta para cima
&rarr; &rightarrow; &rightarrow; &srarr; &#x02192; &#8594; seta direita
&darr; &downarrow; &downarrow; &shortdownarrow; &#x02193; &#8595; seta para baixo
&harr; &leftrightarrow; &leftrightarrow; &#x02194; &#8596; seta esquerda-direita
&nlarr; &#x0219a; &#8602; seta esquerda cortada
&nrarr; &nrightarrow; &#x0219b; &#8603; seta direita cortada
&rarrw; &rightsquigarrow; &#x0219d; &#8605; seta ondulada para a direita
&larr; &twoheadleftarrow; &#x0219e; &#8606; seta de duas pontas esquerda
&uarr; &#x0219f; &#8607; seta de duas pontas para cima
&rarr; &twoheadrightarrow; &#x021a0; &#8608; seta de duas pontas para a direita
&darr; &#x021a1; &#8609; seta de duas pontas para baixo
&larrtl; &leftarrowtail; &#x021a2; &#8610; seta esquerda com cauda
&rarrtl; &rightarrowtail; &#x021a3; &#8611; seta direita com cauda
&leftteearrow; &mapstoleft; &#x021a4; &#8612; seta esquerda barra
&upteearrow; &mapstoup; &#x021a5; &#8613; seta para cima, barra
&map; &rightteearrow; &mapsto; &#x021a6; &#8614; seta direita, barra
&ruledelayed; &#x029f4; &#10740; dois pontos, seta direita; rule-delayed
&larrlp; &looparrowleft; &#x021ab; &#8619; seta esquerda com laço
&rarrlp; &looparrowright; &#x021ac; &#8620; seta direita com laço
&harrw; &leftrightsquigarrow; &#x021ad; &#8621; seta onda esquerda direita
&nharr; &nleftrightarrow; &#x021ae; &#8622; seta esquerda direita, traço
&lsh; &#x021b0; &#8624; seta para cima com ponta para a esquerda
&rsh; &#x021b1; &#8625; seta para cima com ponta para a direita
&ldsh; &#x021b2; &#8626; seta para baixo com ponta para a esquerda
&rdsh; &#x021b3; &#8627; seta para baixo com ponta para a direita
&crarr; &#x021b5; &#8629; seta para baixo com canto esquerdo
&cularr; &curvearrowleft; &#x021b6; &#8630; seta semicírculo superior anti-horária
&curarr; &curvearrowright; &#x021b7; &#8631; seta de semicírculo superior horária
&olarr; &circlearrowleft; &#x021ba; &#8634; seta circular aberta anti-horária
&orarr; &circlearrowright; &#x021bb; &#8635; seta circular aberta horária
&lharu; &leftvector; &leftharpoonup; &#x021bc; &#8636; arpão esquerda, farpa para cima
&lhard; &leftharpoondown; &downleftvector; &#x021bd; &#8637; arpão esquerda, farpa para baixo
&uharr; &upharpoonright; &rightupvector; &#x021be; &#8638; arpão para cima, farpa para a direita
&uharl; &upharpoonleft; &leftupvector; &#x021bf; &#8639; arpão para cima, farpa para a esquerda
&rharu; &rightvector; &rightharpoonup; &#x021c0; &#8640; arpão direita, farpa para cima
&rhard; &rightharpoondown; &downrightvector; &#x021c1; &#8641; arpão direita, farpa para baixo
&dharr; &rightdownvector; &downharpoonright; &#x021c2; &#8642; arpão para baixo, farpa para a direita
&dharl; &leftdownvector; &downharpoonleft; &#x021c3; &#8643; arpão para baixo, farpa para a esquerda
&rlarr; &rightleftarrows; &rightarrowleftarrow; &#x021c4; &#8644; seta direita sobre seta esquerda
&udarr; &uparrowdownarrow; &#x021c5; &#8645; seta para cima para a esquerda da seta para baixo
&lrarr; &leftrightarrows; &leftarrowrightarrow; &#x021c6; &#8646; seta esquerda sobre seta direita
&llarr; &leftleftarrows; &#x021c7; &#8647; duas setas, esquerda
&uuarr; &upuparrows; &#x021c8; &#8648; duas setas para cima
&rrarr; &rightrightarrows; &#x021c9; &#8649; duas setas para a direita
&ddarr; &downdownarrows; &#x021ca; &#8650; duas setas para baixo
&lrhar; &reverseequilibrium; &leftrightharpoons; &#x021cb; &#8651; arpão esquerda sobre o arpão direita
&rlhar; &rightleftharpoons; &equilibrium; &#x021cc; &#8652; arpão da direita sobre arpão da esquerda
&nlarr; &nleftarrow; &#x021cd; &#8653; seta dupla para a esquerda cortada
&nharr; &nleftrightarrow; &#x021ce; &#8654; seta dupla esquerda direita cortada
&nrarr; &nrightarrow; &#x021cf; &#8655; seta dupla para a direita com traço
&larr; &leftarrow; &doubleleftarrow; &#x021d0; &#8656; seta dupla para a esquerda
&uarr; &uparrow; &doubleuparrow; &#x021d1; &#8657; seta dupla para cima
&rarr; &rightarrow; &implies; &doublerightarrow; &#x021d2; &#8658; seta dupla para a direita
&darr; &downarrow; &doubledownarrow; &#x021d3; &#8659; seta dupla para baixo
&harr; &leftrightarrow; &doubleleftrightarrow; &iff; &#x021d4; &#8660; seta dupla esquerda direita
&laarr; &lleftarrow; &#x021da; &#8666; seta tripla para a esquerda
&raarr; &rrightarrow; &#x021db; &#8667; seta tripla para a direita
&zigrarr; &#x021dd; &#8669; seta zigzag para a direita
&larrb; &leftarrowbar; &#x021e4; &#8676; seta esquerda para barra
&rarrb; &rightarrowbar; &#x021e5; &#8677; seta direita para barra
&duarr; &downarrowuparrow; &#x021f5; &#8693; seta para baixo para a esquerda da seta para cima
&loarr; &#x021fd; &#8701; seta de cabeça aberta para a esquerda
&roarr; &#x021fe; &#8702; seta de cabeça aberta para a direita
&hoarr; &#x021ff; &#8703; seta esquerda direita aberta
&xlarr; &longleftarrow; &longleftarrow; &#x027f5; &#10229; seta longa para a esquerda
&xlarr; &longleftarrow; &doublelongleftarrow; &#x027f8; &#10232; seta dupla longa para a esquerda
&xrarr; &longrightarrow; &longrightarrow; &#x027f6; &#10230; seta longa para a direita
&xharr; &longleftrightarrow; &longleftrightarrow; &#x027f7; &#10231; seta longa esquerda direita
&xrarr; &longrightarrow; &doublelongrightarrow; &#x027f9; &#10233; seta dupla longa para a direita
&xharr; &longleftrightarrow; &#x027fa; &#10234; seta dupla longa esquerda direita
&xmap; &longmapsto; &#x027fc; &#10236; seta longa para a direita da barra
&dzigrarr; &#x027ff; &#10239; seta longa para a direita
&nvlarr; &#x02902; &#10498; seta dupla para a esquerda com traço vertical
&nvrarr; &#x02903; &#10499; seta dupla para a direita com traço vertical
&nvharr; &#x02904; &#10500; seta dupla esquerda direita com traço vertical
&map; &#x02905; &#10501; seta de duas pontas para a direita da barra
&lbarr; &#x0290c; &#10508; seta esquerda com traço duplo
&rbarr; &bkarow; &#x0290d; &#10509; seta direita com traço duplo
&lbarr; &#x0290e; &#10510; seta de traço triplo para a esquerda
&rbarr; &dbkarow; &#x0290f; &#10511; seta de traço triplo para a direita
&rbarr; &drbkarow; &#x02910; &#10512; seta de duas pontas para a direita com traço triplo
&ddotrahd; &#x02911; &#10513; seta direita com haste pontilhada
&uparrowbar; &#x02912; &#10514; seta para cima para barra
&downarrowbar; &#x02913; &#10515; seta para baixo para barra
&rarrtl; &#x02916; &#10518; seta de duas pontas para a direita com cauda
&latail; &#x02919; &#10521; cauda de seta esquerda
&ratail; &#x0291a; &#10522; cauda de seta direita
&latail; &#x0291b; &#10523; cauda de seta dupla para a esquerda
&ratail; &#x0291c; &#10524; cauda de seta dupla para a direita
&larrfs; &#x0291d; &#10525; seta esquerda para diamante preto
&rarrfs; &#x0291e; &#10526; seta direita para diamante preto
&larrbfs; &#x0291f; &#10527; seta esquerda da barra ao diamante preto
&rarrbfs; &#x02920; &#10528; seta direita da barra para o diamante preto
&nwarhk; &#x02923; &#10531; seta noroeste com gancho
&nearhk; &#x02924; &#10532; flecha nordeste com gancho
&searhk; &hksearow; &#x02925; &#10533; seta sudeste com gancho
&swarhk; &hkswarow; &#x02926; &#10534; seta sudoeste com gancho
&nwnear; &#x02927; &#10535; seta noroeste e seta nordeste
&nesear; &toea; &#x02928; &#10536; seta nordeste e seta sudeste
&seswar; &tosa; &#x02929; &#10537; seta sudeste e seta sudoeste
&swnwar; &#x0292a; &#10538; seta sudoeste e seta noroeste
&rarrc; &#x02933; &#10547; seta ondulada para a direita
&ldca; &#x02936; &#10550; seta para baixo e curvando para a esquerda
&rdca; &#x02937; &#10551; seta para baixo e curvando para a direita
&cudarrl; &#x02938; &#10552; arco do lado direito seta no sentido horário
&larrpl; &#x02939; &#10553; arco do lado esquerdo no sentido anti-horário
&curarrm; &#x0293c; &#10556; arco superior seta no sentido horário com menos
&cularrp; &#x0293d; &#10557; seta do arco superior no sentido anti-horário com mais
&rarrpl; &#x02945; &#10565; seta direita com mais abaixo
&harrcir; &#x02948; &#10568; seta esquerda direita através de círculo
&uarrocir; &#x02949; &#10569; seta de duas pontas para cima do círculo
&lurdshar; &#x0294a; &#10570; farpa esquerda para cima direita farpa para baixo arpão
&ldrushar; &#x0294b; &#10571; farpa esquerda para baixo direita farpa para cima arpão
&leftrightvector; &#x0294e; &#10574; farpa esquerda para cima direita farpa para arpão
&rightupdownvector; &#x0294f; &#10575; para cima farpa direita para baixo farpa arpão direito
&downleftrightvector; &#x02950; &#10576; farpa esquerda para baixo direita farpa para baixo arpão
&leftupdownvector; &#x02951; &#10577; cima farpa esquerda baixo farpa esquerda arpão
&leftvectorbar; &#x02952; &#10578; arpão esquerda com farpa até a barra
&rightvectorbar; &#x02953; &#10579; arpão direita com farpa até a barra
&rightupvectorbar; &#x02954; &#10580; arpão para cima com farpa direita na barra
&rightdownvectorbar; &#x02955; &#10581; arpão para baixo com farpa à direita da barra
&downleftvectorbar; &#x02956; &#10582; arpão esquerda com farpa até a barra
&downrightvectorbar; &#x02957; &#10583; arpão direita com farpa até a barra
&leftupvectorbar; &#x02958; &#10584; arpão para cima com farpa da esquerda para a barra
&leftdownvectorbar; &#x02959; &#10585; arpão para baixo com farpa da esquerda para a barra
&leftteevector; &#x0295a; &#10586; arpão esquerda com farpa para cima da barra
&rightteevector; &#x0295b; &#10587; arpão direita com farpa para cima da barra
&rightupteevector; &#x0295c; &#10588; arpão para cima com farpa direto da barra
&rightdownteevector; &#x0295d; &#10589; arpão para baixo com farpa direto da barra
&downleftteevector; &#x0295e; &#10590; arpão esquerda com farpa para baixo da barra
&downrightteevector; &#x0295f; &#10591; arpão direita com farpa para baixo da barra
&leftupteevector; &#x02960; &#10592; arpão para cima com farpa esquerda da barra
&leftdownteevector; &#x02961; &#10593; arpão para baixo com farpa esquerda da barra
&lhar; &#x02962; &#10594; arpão esquerda com farpa para cima acima do arpão esquerda com farpa para baixo
&uhar; &#x02963; &#10595; arpão para cima com farpa esquerda ao lado arpão para cima com farpa direita
&rhar; &#x02964; &#10596; arpão direita com farpa para cima acima para arpão direita com farpa para baixo
&dhar; &#x02965; &#10597; arpão para baixo com farpa esquerda ao lado arpão para baixo com farpa direita
&luruhar; &#x02966; &#10598; arpão esquerda com farpa para cima acima do arpão direita com farpa para cima
&ldrdhar; &#x02967; &#10599; arpão esquerda com farpa para baixo acima do arpão direita com farpa para baixo
&ruluhar; &#x02968; &#10600; arpão direita com farpa para cima acima do arpão esquerda com farpa para cima
&rdldhar; &#x02969; &#10601; arpão direita com farpa para baixo acima do arpão esquerda com farpa para baixo
&lharul; &#x0296a; &#10602; arpão esquerda com farpa acima do longo traço
&llhard; &#x0296b; &#10603; arpão esquerda com farpa abaixo do longo traço
&rharul; &#x0296c; &#10604; arpão direita com farpa acima do longo traço
&lrhard; &#x0296d; &#10605; arpão direita com farpa abaixo do longo traço
&udhar; &upequilibrium; &#x0296e; &#10606; arpão p/ cima com farpa esquerda ao lado arpão para baixo com farpa direita
&duhar; &reverseupequilibrium; &#x0296f; &#10607; arpão para baixo com farpa esquerda ao lado arpão para cima com farpa direita
&roundimplies; &#x02970; &#10608; seta dupla direita com cabeça arredondada
&erarr; &#x02971; &#10609; igual acima da seta direita
&simrarr; &#x02972; &#10610; operador til acima da seta direita
&larrsim; &#x02973; &#10611; seta esquerda acima do operador til
&rarrsim; &#x02974; &#10612; seta direita acima do operador til
&rarrap; &#x02975; &#10613; seta direita acima quase igual a
&ltlarr; &#x02976; &#10614; seta esquerda menor que acima
&gtrarr; &#x02978; &#10616; maior do que acima da seta direita
&subrarr; &#x02979; &#10617; subconjunto acima da seta direita
&suplarr; &#x0297b; &#10619; superconjunto acima da seta esquerda
&lfisht; &#x0297c; &#10620; cauda de peixe esquerda
&rfisht; &#x0297d; &#10621; cauda de peixe direita
Emoticons
Caracter HTML HEX DEC Descrição
&cudarrr; &#x02935; &#10549; seta para a direita e curvando para baixo
&larrhk; &hookleftarrow; &#x021a9; &#8617; seta esquerda com gancho
&rarrhk; &hookrightarrow; &#x021aa; &#8618; seta direita com gancho
&varr; &updownarrow; &updownarrow; &#x02195; &#8597; seta para cima e para baixo
&nwarr; &nwarrow; &#x02196; &#8598; seta noroeste
&nearr; &nearrow; &#x02197; &#8599; seta nordeste
&searr; &searrow; &#x02198; &#8600; seta sudeste
&swarr; &swarrow; &#x02199; &#8601; seta sudoeste
&phone; &#x0260e; &#9742; telefone preto
&female; &#x02640; &#9792; signo feminino
&male; &#x02642; &#9794; signo masculino
Caracteres Gráficos: Desenho
Caracter HTML HEX DEC Descrição
&boxh; &horizontalline; &#x02500; &#9472; parte de caixa: linha horizontal
&boxv; &#x02502; &#9474; parte de caixa: linha vertical
&boxdr; &#x0250c; &#9484; parte de caixa: canto superior esquerdo
&boxdl; &#x02510; &#9488; desenho da caixa canto superior direito
&boxur; &#x02514; &#9492; parte de caixa: canto inferior esquerdo
&boxul; &#x02518; &#9496; parte de caixa: canto inferior direito
&boxvr; &#x0251c; &#9500; parte de caixa: linha central direita
&boxvl; &#x02524; &#9508; parte de caixa: linha central esquerda
&boxhd; &#x0252c; &#9516; parte de caixa: linha para baixo e horizontal
&boxhu; &#x02534; &#9524; parte de caixa: iluminados e horizontais
&boxvh; &#x0253c; &#9532; parte de caixa: de linha vertical e horizontal
&boxh; &#x02550; &#9552; parte de caixa: dupla horizontal
&boxv; &#x02551; &#9553; parte de caixa: dupla vertical
&boxdr; &#x02552; &#9554; parte de caixa: para baixo simples e duplo direito
&boxdr; &#x02553; &#9555; parte de caixa: para baixo duplo e único direito
&boxdr; &#x02554; &#9556; os desenhos da caixa dobram para baixo e para a direita
&boxdl; &#x02555; &#9557; parte de caixa: para baixo simples e duplo esquerdo
&boxdl; &#x02556; &#9558; parte de caixa: para baixo duplo e único esquerdo
&boxdl; &#x02557; &#9559; desenhos da caixa dobrar para baixo e para a esquerda
&boxur; &#x02558; &#9560; parte de caixa: s simples e duplas à direita
&boxur; &#x02559; &#9561; caixa de desenhos dupla e direita simples
&boxur; &#x0255a; &#9562; os desenhos da caixa dobram e correm
&boxul; &#x0255b; &#9563; parte de caixa: para cima simples e duplo esquerdo
&boxul; &#x0255c; &#9564; parte de caixa: duplo e esquerdo simples
&boxul; &#x0255d; &#9565; os desenhos da caixa dobram e saem
&boxvr; &#x0255e; &#9566; parte de caixa: vertical simples e duplo direito
&boxvr; &#x0255f; &#9567; parte de caixa: vertical duplo e direito simples
&boxvr; &#x02560; &#9568; parte de caixa: dupla vertical e direita
&boxvl; &#x02561; &#9569; parte de caixa: vertical simples e duplo esquerdo
&boxvl; &#x02562; &#9570; parte de caixa: dupla vertical e esquerda simples
&boxvl; &#x02563; &#9571; parte de caixa: duplo vertical e esquerdo
&boxhd; &#x02564; &#9572; parte de caixa: para baixo simples e duplo horizontal
&boxhd; &#x02565; &#9573; parte de caixa: para baixo duplo e horizontal simples
&boxhd; &#x02566; &#9574; parte de caixa: dobrar para baixo e horizontal
&boxhu; &#x02567; &#9575; parte de caixa: para cima simples e duplo horizontal
&boxhu; &#x02568; &#9576; parte de caixa: duplo e horizontal simples
&boxhu; &#x02569; &#9577; parte de caixa: dobrados e horizontais
&boxvh; &#x0256a; &#9578; parte de caixa: vertical simples e horizontal duplo
&boxvh; &#x0256b; &#9579; parte de caixa: dupla vertical e simples horizontal
&boxvh; &#x0256c; &#9580; parte de caixa: duplo vertical e horizontal
&uhblk; &#x02580; &#9600; meio bloco superior
&lhblk; &#x02584; &#9604; meio bloco inferior
&block; &#x02588; &#9608; bloco completo
&blk14; &#x02591; &#9617; sombra clara
&blk12; &#x02592; &#9618; tom médio
&blk34; &#x02593; &#9619; sombra escura
Figuras Geométricas
Caracter HTML HEX DEC Descrição
&squ; &square; &square; &#x025a1; &#9633; quadrado branco
&squf; &squarf; &blacksquare; &filledverysmallsquare; &#x025aa; &#9642; quadrado pequeno preto
&emptyverysmallsquare; &#x025ab; &#9643; quadrado pequeno branco
&rect; &#x025ad; &#9645; retângulo branco
&marker; &#x025ae; &#9646; retângulo preto vertical
&fltns; &#x025b1; &#9649; paralelogramo branco
&xutri; &bigtriangleup; &#x025b3; &#9651; triângulo branco para cima
&utrif; &blacktriangle; &#x025b4; &#9652; triângulo pequeno preto para cima
&utri; &triangle; &#x025b5; &#9653; triângulo pequeno branco para cima
&rtrif; &blacktriangleright; &#x025b8; &#9656; triângulo pequeno preto para a direita
&rtri; &triangleright; &#x025b9; &#9657; triângulo pequeno branco para a direita
&xdtri; &bigtriangledown; &#x025bd; &#9661; triângulo branco para baixo
&dtrif; &blacktriangledown; &#x025be; &#9662; triângulo pequeno preto para baixo
&dtri; &triangledown; &#x025bf; &#9663; ponto baixo branco
&ltrif; &blacktriangleleft; &#x025c2; &#9666; triângulo pequeno preto para a esquerda
&ltri; &triangleleft; &#x025c3; &#9667; triângulo pequeno branco para a esquerda
&loz; &lozenge; &#x025ca; &#9674; pastilha
&cir; &#x025cb; &#9675; círculo branco
&tridot; &#x025ec; &#9708; triângulo branco para cima com ponto
&xcirc; &bigcirc; &#x025ef; &#9711; grande círculo
&ultri; &#x025f8; &#9720; triângulo superior esquerdo
&urtri; &#x025f9; &#9721; triângulo superior direito
&lltri; &#x025fa; &#9722; triângulo inferior esquerdo
&emptysmallsquare; &#x025fb; &#9723; quadrado médio branco
&filledsmallsquare; &#x025fc; &#9724; quadrado médio preto
Acentos
Caracter HTML HEX DEC Descrição
´ &acute; &diacriticalacute; &#x000b4; &#180; acento agudo
^ &hat; &#x0005e; &#94; acento circunflexo
ˆ &circ; &#x002c6; &#710; acento circunflexo
` &grave; &diacriticalgrave; &#x00060; &#96; acento grave
˘ &breve; &#x002d8; &#728; breve
¸ &cedil; &cedilla; &#x000b8; &#184; cedilha
¨ &dot; &die; &uml; &#x000a8; &#168; trema
&apos; &#x00027; &#39; apóstrofe
˜ &tilde; &#x002dc; &#732; til pequeno
˙ &dot; &#x002d9; &#729; ponto acima
ˇ &caron; &#x002c7; &#711; caron
˚ &ring; &#x002da; &#730; anel acima
˛ &ogon; &#x002db; &#731; ogonek
˝ &dblac; &#x002dd; &#733; acento agudo duplo
_ &UnderBar; &#x00332; &#818; traço subescrito
Caracteres Acentuados
Caracter HTML HEX DEC Descrição
À &Agrave; &#x000c0; &#192; A grave
Á &Aacute; &#x000c1; &#193; A agudo
 &Acirc; &#x000c2; &#194; A circunflexo
à &Atilde; &#x000c3; &#195; A til
Ä &Auml; &#x000c4; &#196; A trema
Å &Aring; &#x000c5; &#197; A anel
&Aelig; &Aelig; &#x000c6; &#198; Ae
à &agrave; &#x000e0; &#224; a grave
á &aacute; &#x000e1; &#225; a agudo
â &acirc; &#x000e2; &#226; a circunflexo
ã &atilde; &#x000e3; &#227; a til
ä &auml; &#x000e4; &#228; a trema
å &aring; &#x000e5; &#229; a anel acima
æ &aelig; &#x000e6; &#230; ae
Ā &Amacr; &#x00100; &#256; A mácron
ā &amacr; &#x00101; &#257; a mácron
Ă &Abreve; &#x00102; &#258; A breve
ă &abreve; &#x00103; &#259; a breve
Ą &Aogon; &#x00104; &#260; A ogonek
ą &aogon; &#x00105; &#261; a ogonek
Ć &Cacute; &#x00106; &#262; C com agudo
ć &cacute; &#x00107; &#263; c com agudo
Ĉ &Ccirc; &#x00108; &#264; C com circunflexo
ĉ &ccirc; &#x00109; &#265; c com circunflexo
Ċ &Cdot; &#x0010a; &#266; C com ponto acima
ċ &cdot; &#x0010b; &#267; c com ponto acima
č &ccaron; &#x0010c; &#268; maiúscula c com caron
č &ccaron; &#x0010d; &#269; minúscula c com caron
ç &ccedil; &#x000c7; &#199; c com cedilha
Ď &Dcaron; &#x0010e; &#270; D caron
ď &dcaron; &#x0010f; &#271; d caron
Đ &Dstrok; &#x00110; &#272; D com traço
đ &dstrok; &#x00111; &#273; d com traço
È &Egrave; &#x000e8; &#232; E grave
è &egrave; &#x000c8; &#200; e com grave
é &eacute; &#x000c9; &#201; e com agudo
é &eacute; &#x000e9; &#233; e agudo
ê &ecirc; &#x000ea; &#234; e circunflexo
ê &ecirc; &#x000ca; &#202; e com circunflexo
Ë &Euml; &#x000cb; &#203; E com trema
ë &euml; &#x000eb; &#235; e trema
Ē &Emacr; &#x00112; &#274; E mácron
ē &emacr; &#x00113; &#275; e mácron
Ė &Edot; &#x00116; &#278; E ponto
ė &edot; &#x00117; &#279; e ponto
Ę &Eogon; &#x00118; &#280; E com ogonek
ę &eogon; &#x00119; &#281; e com ogonek
Ě &Ecaron; &#x0011a; &#282; E caron
ě &ecaron; &#x0011b; &#283; e caron
ð &eth; &#x000f0; &#240; eth minúsculo
&Eth; &Eth; &#x000d0; &#208; eth maiúsculo
Ĝ &Gcirc; &#x0011c; &#284; G circunflexo
ĝ &gcirc; &#x0011d; &#285; g circunflexo
Ğ &Gbreve; &#x0011e; &#286; G breve
ğ &gbreve; &#x0011f; &#287; g breve
Ġ &Gdot; &#x00120; &#288; G com ponto acima
ġ &gdot; &#x00121; &#289; g com ponto acima
ǵ &gacute; &#x001f5; &#501; g com agudo
Ĥ &Hcirc; &#x00124; &#292; H circunflexo
ĥ &hcirc; &#x00125; &#293; h circunflexo
Ħ &Hstrok; &#x00126; &#294; H com traço
ħ &hstrok; &#x00127; &#295; h com traço
ì &igrave; &#x000ec; &#236; i grave
í &iacute; &#x000ed; &#237; i agudo
î &icirc; &#x000ee; &#238; i circunflexo
ï &iuml; &#x000ef; &#239; i trema
Ĩ &itilde; &#x00129; &#297; I til
ĩ &itilde; &#x00128; &#296; i til
Ī &Imacr; &#x0012a; &#298; I com mácron
ī &imacr; &#x0012b; &#299; i com mácron
Į &Iogon; &#x0012e; &#302; I com ogonek
į &iogon; &#x0012f; &#303; i com ogonek
İ &Idot; &#x00130; &#304; I com ponto
IJ &IJlig; &#x00132; &#306; ligadura IJ
ij &ijlig; &#x00133; &#307; ligadura ij
Ĵ &Jcirc; &#x00134; &#308; J circunflexo
ĵ &jcirc; &#x00135; &#309; j circunflexo
Ķ &Kcedil; &#x00136; &#310; K com cedilha
ķ &kcedil; &#x00137; &#311; k com cedilha
ĸ &kgreen; &#x00138; &#312; kra minúsculo
Ĺ &Lacute; &#x00139; &#313; L agudo
ĺ &lacute; &#x0013a; &#314; l agudo
Ļ &Lcedil; &#x0013b; &#315; L com cedilha
ļ &lcedil; &#x0013c; &#316; l com cedilha
Ľ &Lcaron; &#x0013d; &#317; L com caron
ľ &lcaron; &#x0013e; &#318; l com caron
Ŀ &Lmidot; &#x0013f; &#319; L com ponto
ŀ &lmidot; &#x00140; &#320; l com ponto
Ł &Lstrok; &#x00141; &#321; L com traço
ł &lstrok; &#x00142; &#322; l com traço
Ń &Nacute; &#x00143; &#323; N com agudo
ń &nacute; &#x00144; &#324; n com agudo
Ņ &Ncedil; &#x00145; &#325; N com cedilha
ņ &ncedil; &#x00146; &#326; n com cedilha
Ň &Ncaron; &#x00147; &#327; N com caron
ň &ncaron; &#x00148; &#328; n com caron
ʼn &napos; &#x00149; &#329; n precedida de apóstrofo
ñ &ntilde; &#x000d1; &#209; n com til
ò &ograve; &#x000f2; &#242; o grave
ó &oacute; &#x000f3; &#243; o agudo
ô &ocirc; &#x000f4; &#244; o circunflexo
õ &otilde; &#x000f5; &#245; o til
ö &ouml; &#x000f6; &#246; o com trema
ø &oslash; &#x000f8; &#248; o com traço
Ō &Omacr; &#x0014c; &#332; O com macron
ō &omacr; &#x0014d; &#333; o com mácron
Ő &Odblac; &#x00150; &#336; O com duplo agudo
ő &odblac; &#x00151; &#337; o com duplo agudo
&Oegig; &Oelig; &#x00152; &#338; ligadura OE maiúscula
œ &oelig; &#x00153; &#339; ligadura oe minúscula
Ŕ &Racute; &#x00154; &#340; R com agudo
ŕ &racute; &#x00155; &#341; r com agudo
Ŗ &Rcedil; &#x00156; &#342; R com cedilha
ŗ &rcedil; &#x00157; &#343; r com cedilha
Ř &Rcaron; &#x00158; &#344; R com caron
ř &rcaron; &#x00159; &#345; r minúscula com caron
Ś &Sacute; &#x0015a; &#346; S com agudo
ś &sacute; &#x0015b; &#347; s com agudo
Ŝ &Scirc; &#x0015c; &#348; S com circunflexo
ŝ &scirc; &#x0015d; &#349; s com circunflexo
Ş &Scedil; &#x0015e; &#350; S com cedilha
ş &scedil; &#x0015f; &#351; s com cedilha
Š &Scaron; &#x00160; &#352; S s com caron
š &scaron; &#x00161; &#353; s com caron
Ţ &Tcedil; &#x00162; &#354; T com cedilha
ţ &tcedil; &#x00163; &#355; t com cedilha
Ť &Tcaron; &#x00164; &#356; T com caron
ť &tcaron; &#x00165; &#357; t com caron
Ŧ &Tstrok; &#x00166; &#358; T com traço
ŧ &tstrok; &#x00167; &#359; t com traço
ù &ugrave; &#x000f9; &#249; u grave
ú &uacute; &#x000fa; &#250; u agudo
û &ucirc; &#x000fb; &#251; u circunflexo
ü &uuml; &#x000fc; &#252; u com trema
Ũ &Utilde; &#x00168; &#360; U com til
ũ &utilde; &#x00169; &#361; u com til
Ū &Umacr; &#x0016a; &#362; U com mácron
ū &umacr; &#x0016b; &#363; u com mácron
Ŭ &Ubreve; &#x0016c; &#364; U breve
ŭ &ubreve; &#x0016d; &#365; u breve
Ů &Uring; &#x0016e; &#366; U com anel
ů &uring; &#x0016f; &#367; u com anel
Ű &Udblac; &#x00170; &#368; U com duplo agudo
ű &udblac; &#x00171; &#369; u com duplo agudo
Ų &Uogon; &#x00172; &#370; U com ogonek
ų &uogon; &#x00173; &#371; u com ogonek
Ŵ &Wcirc; &#x00174; &#372; W com circunflexo
ŵ &wcirc; &#x00175; &#373; w com circunflexo
Ŷ &Ycirc; &#x00176; &#374; Y com circunflexo
ŷ &ycirc; &#x00177; &#375; y com circunflexo
Ÿ &Yuml; &#x00178; &#376; Y com trema
ÿ &yuml; &#x000ff; &#255; y com trema
Ý &Yacute; &#x000dd; &#221; Y com agudo
ý &yacute; &#x000fd; &#253; y com agudo
Ź &Zacute; &#x00179; &#377; Z com agudo
ź &zacute; &#x0017a; &#378; z com agudo
Ż &Zdot; &#x0017b; &#379; Z com ponto acima
ż &zdot; &#x0017c; &#380; z com ponto acima
Ž &Zcaron; &#x0017d; &#381; Z com caron
ž &zcaron; &#x0017e; &#382; z com caron
Ƶ &imped; &#x001b5; &#437; Z cortado
Ligaduras de Carateres Latinos
Caracter HTML HEX DEC Descrição
IJ &IJlig; &#x00132; &#306; ligadura IJ (maiúsculo)
ij &ijlig; &#x00133; &#307; ligadura ij (minúsculo)
Œ &OElig; &#x00152; amp;Œ; ligadura OE maiúscula
œ &oelig; &#x00153; &#339; ligadura oe minúscula
&fflig; &#x0fb00; &#64256; ligadura ff
&filig; &#x0fb01; &#64257; ligadura fi
&fllig; &#x0fb02; &#64258; ligadura fl
&ffilig; &#x0fb03; &#64259; ligadura ffi
&ffllig; &#x0fb04; &#64260; ligadura ffl
Carateres Não Latinos
Caracter HTML HEX DEC Descrição
ŋ &eng; &#x0014b; &#331; minúscula eng
Þ &Thorn; &#x000de; &#222; ‘thorn’ maiúsculo
þ &thorn; &#x000fe; &#254; ‘thorn’ minúsculo
ß &szlig; &#x000df; &#223; ‘eszett’ alemão
Caracteres script
Caracter HTML HEX DEC Descrição
𝒶 &ascr; &#x1d49c; &#119964; a minúsculo
𝒷 &bscr; &#x1d49D; &#119965; b
𝒸 &cscr; &#x1d49e; &#119966; c
𝒹 &dscr; &#x1d49f; &#119967; d
&escr; &#x1d4a0; &#119968; e
𝒻 &fscr; &#x1d4a1; &#119969; e
&gscr; &#x1d4a2; &#119970; g
𝒽 &hscr; &#x1d4a3; &#119971; h
𝒾 &iscr; &#x1d4a4; &#119972; i
𝒿 &jscr; &#x1d4a5; &#119973; j
𝓀 &kscr; &#x1d4a6; &#119974; k
𝓁 &lscr; &#x1d4a7; &#119975; l
𝓂 &mscr; &#x1d4a8; &#119976; m
𝓃 &nscr; &#x1d4a9; &#119977; n
&oscr; &#x1d4aa; &#119978; o
𝓅 &pscr; &#x1d4ab; &#119979; p
𝓆 &qscr; &#x1d4ac; &#119980; q
𝓇 &rscr; &#x1d4ad; &#119981; r
𝓈 &sscr; &#x1d4ae; &#119982; s
𝓉 &tscr; &#x1d4af; &#119983; t
𝓊 &uscr; &#x1d4b0; &#119984; u
𝓋 &vscr; &#x1d4b1; &#119985; v
𝓌 &wscr; &#x1d4b2; &#119986; w
𝓍 &xscr; &#x1d4b3; &#119987; x
𝓎 &yscr; &#x1d4b4; &#119988; y
𝓏 &zscr; &#x1d4b5; &#119989; z
Caracter HTML HEX DEC Descrição
𝒜 &Ascr; &#x1d4b6; &#119989; A maiúsculo
&Bscr; &#x1d4b7; &#119990; B
𝒞 &Cscr; &#x1d4b8; &#119991; C
𝒟 &Dscr; &#x1d4b9; &#119992; D
&Escr; &#x1d4ba; &#119993; E
&Fscr; &#x1d4bb; &#119994; F
𝒢 &Gscr; &#x1d4bc; &#119995; G
&Hscr; &#x1d4bd; &#119996; H
&Iscr; &#x1d4be; &#119997; I
𝒥 &Jscr; &#x1d4bf; &#119998; J
𝒦 &Kscr; &#x1d4c0; &#119999; K
&Lscr; &#x1d4c1; &#120000; L
&Mscr; &#x1d4c2; &#120001; M
𝒩 &Nscr; &#x1d4c3; &#120002; N
𝒪 &Oscr; &#x1d4c4; &#120003; O
𝒫 &Pscr; &#x1d4c5; &#120004; P
𝒬 &Qscr; &#x1d4c6; &#120005; Q
&Rscr; &#x1d4c7; &#120006; R
𝒮 &Sscr; &#x1d4c8; &#120007; S
𝒯 &Tscr; &#x1d4c9; &#120008; T
𝒰 &Uscr; &#x1d4ca; &#120009; U
𝒱 &Vscr; &#x1d4cb; &#120010; V
𝒲 &Wscr; &#x1d4cc; &#120011; W
𝒳 &Xscr; &#x1d4cd; &#120012; X
𝒴 &Yscr; &#x1d4ce; &#120013; Y
𝒵 &Zscr; &#x1d4ce; &#120014; Z
Caracteres Fraktur
Caracter HTML HEX DEC Descrição
𝔞 &afr; &#x1d504; &#120068; a minúsculo
𝔟 &bfr; &#x1d505; &#120069; b
𝔠 &cfr; &#x1d506; &#120070; c
𝔡 &dfr; &#x1d507; &#120071; d
𝔢 &efr; &#x1d508; &#120072; e
𝔣 &ffr; &#x1d509; &#120073; f
𝔤 &gfr; &#x1d50a; &#120074; g
𝔥 &hfr; &#x1d50b; &#120075; h
𝔦 &ifr; &#x1d50c; &#120076; i
𝔧 &jfr; &#x1d50d; &#120077; j
𝔨 &kfr; &#x1d50e; &#120078; k
𝔩 &lfr; &#x1d50f; &#120079; l
𝔪 &mfr; &#x1d510; &#120080; m
𝔫 &nfr; &#x1d511; &#120081; n
𝔬 &ofr; &#x1d512; &#120082; o
𝔭 &pfr; &#x1d513; &#120083; p
𝔮 &qfr; &#x1d514; &#120084; q
𝔯 &rfr; &#x1d515; &#120085; r
𝔰 &sfr; &#x1d516; &#120086; s
𝔱 &tfr; &#x1d517; &#120087; t
𝔲 &ufr; &#x1d518; &#120088; u
𝔳 &vfr; &#x1d519; &#120089; v
𝔴 &wfr; &#x1d51a; &#120090; w
𝔵 &xfr; &#x1d51b; &#120091; x
𝔶 &yfr; &#x1d51c; &#120092; y
𝔷 &zfr; &#x1d51d; &#120093; z
Caracter HTML HEX DEC Descrição
𝔄 &Afr; &#x1d51e; &#120094; A maiúsculo
𝔅 &Bfr; &#x1d51f; &#120095; B
&Cfr; &#x1d520; &#120096; C
𝔇 &Dfr; &#x1d521; &#120097; D
𝔈 &Efr; &#x1d522; &#120098; E
𝔉 &Ffr; &#x1d523; &#120099; F
𝔊 &Gfr; &#x1d524; &#120100; G
&Hfr; &#x1d525; &#120101; H
&Ifr; &#x1d526; &#120102; I
𝔍 &Jfr; &#x1d527; &#120103; J
𝔎 &Kfr; &#x1d528; &#120104; K
𝔏 &Lfr; &#x1d529; &#120105; L
𝔐 &Mfr; &#x1d52a; &#120106; M
𝔑 &Nfr; &#x1d52b; &#120107; N
𝔒 &Ofr; &#x1d52c; &#120108; O
𝔓 &Pfr; &#x1d52d; &#120109; P
𝔔 &Qfr; &#x1d52e; &#120110; Q
&Rfr; &#x1d52f; &#120111; R
𝔖 &Sfr; &#x1d530; &#120112; S
𝔗 &Tfr; &#x1d531; &#120113; T
𝔘 &Ufr; &#x1d532; &#120114; U
𝔙 &Vfr; &#x1d533; &#120115; V
𝔚 &Wfr; &#x1d534; &#120116; W
𝔛 &Xfr; &#x1d535; &#120117; X
𝔜 &Yfr; &#x1d536; &#120118; Y
&Zfr; &#x1d537; &#120119; Z
Caracteres de traço duplo
Caracter HTML HEX DEC Descrição
𝕒 &aopf; &#x1d538; &#120120; a minúsculo
𝕓 &bopf; &#x1d539; &#120121; b
𝕔 &copf; &#x1d539; &#120122; c
𝕕 &dopf; &#x1d53b; &#120123; d
𝕖 &eopf; &#x1d53c; &#120124; e
𝕗 &fopf; &#x1d53d; &#120125; f
𝕘 &gopf; &#x1d53e; &#120126; g
𝕙 &hopf; &#x1d53e; &#120127; h
𝕚 &iopf; &#x1d540; &#120128; i
𝕛 &jopf; &#x1d541; &#120129; j
𝕜 &kopf; &#x1d542; &#120130; k
𝕝 &lopf; &#x1d543; &#120131; l
𝕞 &mopf; &#x1d544; &#120132; m
𝕟 &nopf; &#x1d545; &#120133; n
𝕠 &oopf; &#x1d546; &#120134; o
𝕡 &popf; &#x1d547; &#120135; p
𝕢 &qopf; &#x1d548; &#120136; q
𝕣 &ropf; &#x1d549; &#120137; r
𝕤 &sopf; &#x1d54a; &#120138; s
𝕥 &topf; &#x1d54b; &#120139; t
𝕦 &uopf; &#x1d54c; &#120140; u
𝕧 &vopf; &#x1d54d; &#120141; v
𝕨 &wopf; &#x1d54e; &#120142; w
𝕩 &xopf; &#x1d54f; &#120143; x
𝕪 &yopf; &#x1d550; &#120144; y
𝕫 &zopf; &#x1d551; &#120145; z
Caracter HTML HEX DEC Descrição
𝔸 &Aopf; &#x1d552; &#120146; A maiúsculo
𝔹 &Bopf; &#x1d553; &#120147; B
&Copf; &#x1d554; &#120148; C
𝔻 &Dopf; &#x1d555; &#120149; D
𝔼 &Eopf; &#x1d556; &#120150; E
𝔽 &Fopf; &#x1d557; &#120151; F
𝔾 &Gopf; &#x1d558; &#120152; G
&Hopf; &#x1d559; &#120153; H
𝕀 &Iopf; &#x1d55a; &#120154; I
𝕁 &Jopf; &#x1d55b; &#120155; J
𝕂 &Kopf; &#x1d55c; &#120156; K
𝕃 &Lopf; &#x1d55d; &#120157; L
𝕄 &Mopf; &#x1d55e; &#120158; M
&Nopf; &#x1d55f; &#120159; N
𝕆 &Oopf; &#x1d560; &#120160; O
&Popf; &#x1d561; &#120161; P
&Qopf; &#x1d562; &#120162; Q
&Ropf; &#x1d563; &#120163; R
𝕊 &Sopf; &#x1d564; &#120164; S
𝕋 &Topf; &#x1d565; &#120165; T
𝕌 &Uopf; &#x1d566; &#120166; U
𝕍 &Vopf; &#x1d567; &#120167; V
𝕎 &Wopf; &#x1d568; &#120168; W
𝕏 &Xopf; &#x1d569; &#120169; X
𝕐 &Yopf; &#x1d56a; &#120170; Y
&Zopf; &#x1d56b; &#120171; Z
Caracteres Gregos
Caracter HTML HEX DEC Descrição
α &alpha; &#x00391; &#913; alfa maiúsculo grego
β &beta; &#x00392; &#914; beta maiúsculo grego
γ &gamma; &#x00393; &#915; gama grega maiúscula
δ &delta; &#x00394; &#916; letra maiúscula grega delta
ε &epsilon; &#x00395; &#917; epsilon com letra maiúscula grega
ζ &zeta; &#x00396; &#918; zeta letra maiúscula grega
η &eta; &#x00397; &#919; letra maiúscula grega eta
θ &theta; &#x00398; &#920; teta maiúscula grega
ι &iota; &#x00399; &#921; letra maiúscula iota
κ &kappa; &#x0039a; &#922; kappa maiúscula
λ &lambda; &#x0039b; &#923; lamda letra maiúscula
μ &mu; &#x0039c; &#924; letra maiúscula mu
ν &nu; &#x0039d; &#925; nu maiúsculo
ξ &xi; &#x0039e; &#926; letra maiúscula xi
ο &omicron; &#x0039f; &#927; omicron maiúsculo
π &pi; &#x003a0; &#928; pi maiúscula
ρ &rho; &#x003a1; &#929; rho maiúsculo
σ &sigma; &#x003a3; &#931; sigma maiúsculo
τ &tau; &#x003a4; &#932; tau maiúsculo
υ &upsilon; &#x003a5; &#933; upsilon maiúsculo
φ &phi; &#x003a6; &#934; letra maiúscula phi
χ &chi; &#x003a7; &#935; maiúsculo chi
ψ &psi; &#x003a8; &#936; letra maiúscula psi
ω &omega; &#x003a9; &#937; ômega letra maiúscula
α &alpha; &#x003b1; &#945; alfa minúsculo
β &beta; &#x003b2; &#946; beta letra minúscula
γ &gamma; &#x003b3; &#947; gama minúscula
δ &delta; &#x003b4; &#948; letra delta
ϵ ε &epsiv; &epsilon; &#x003b5; &#949; epsilon minúsculo
ζ &zeta; &#x003b6; &#950; zeta letra minúscula
η &eta; &#x003b7; &#951; letra minúscula eta
θ &theta; &#x003b8; &#952; letra minúscula teta
ι &iota; &#x003b9; &#953; letra minúscula iota
κ &kappa; &#x003ba; &#954; kappa minúsculo
λ &lambda; &#x003bb; &#955; lamda minúscula
μ &mu; &#x003bc; &#956; letra mi minúscula
ν &nu; &#x003bd; &#957; nu minúsculo
ξ &xi; &#x003be; &#958; letra minúscula xi
ο &omicron; &#x003bf; &#959; omicron minúsculo
π &pi; &#x003c0; &#960; pi minúsculo
ρ &rho; &#x003c1; &#961; minúsculo rho
ς &sigmav; &varsigma; &sigmaf; &#x003c2; &#962; final sigma minúsculo
σ &sigma; &#x003c3; &#963; sigma minúsculo
τ &tau; &#x003c4; &#964; tau minúsculo
υ &upsi; &upsilon; &#x003c5; &#965; letra minúscula upsilon
φ &phi; &phiv; &varphi; &#x003c6; &#966; letra minúscula phi
χ &chi; &#x003c7; &#967; letra minúscula chi
ψ &psi; &#x003c8; &#968; letra minúscula psi
ω &omega; &#x003c9; &#969; letra minúscula ômega
ϑ &thetav; &vartheta; &thetasym; &#x003d1; &#977; letra minúscula theta
υ ϒ &upsi; &upsih; &#x003d2; &#978; Upsilon com símbolo de gancho
φ &straightphi; &#x003d5; &#981; letra minúscula phi
ϖ &piv; &varpi; &#x003d6; &#982; letra minúscula pi
ϝ &gammad; &#x003dc; &#988; letra digamma
ϰ &kappav; &varkappa; &#x003f0; &#1008; símbolo kappa
ϱ &rhov; &varrho; &#x003f1; &#1009; letra rho
ε &epsi; &straightepsilon; &#x003f5; &#1013; épsilon semilunar
϶ &bepsi; &backepsilon; &#x003f6; &#1014; épsilon semilunar invertido
Caracteres Cirílicos
Caracter HTML HEX DEC Descrição
ё &iocy; &#x00401; &#1025; cirílico maiúsculo io
ђ &djcy; &#x00402; &#1026; dje cirílico maiúsculo
ѓ &gjcy; &#x00403; &#1027; cirílico maiúsculo gje
є &jukcy; &#x00404; &#1028; cirílico maiúsculo ucraniano, isto é
ѕ &dscy; &#x00405; &#1029; cirílico maiúsculo dze
і &iukcy; &#x00406; &#1030; cirílico maiúsculo bielorrussa-ucraniana i
ї &yicy; &#x00407; &#1031; cirílico maiúsculo yi
ј &jsercy; &#x00408; &#1032; cirílico maiúsculo je
љ &ljcy; &#x00409; &#1033; cirílico maiúsculo lje
њ &njcy; &#x0040a; &#1034; cirílico maiúsculo nje
ћ &tshcy; &#x0040b; &#1035; cirílico maiúsculo tshe
ќ &kjcy; &#x0040c; &#1036; cirílico maiúsculo kje
ў &ubrcy; &#x0040e; &#1038; cirílico maiúsculo curta u
џ &dzcy; &#x0040f; &#1039; cirílico maiúsculo dzhe
а &acy; &#x00410; &#1040; cirílico maiúsculo a
б &bcy; &#x00411; &#1041; cirílico maiúsculo seja
в &vcy; &#x00412; &#1042; cirílico maiúsculo ve
г &gcy; &#x00413; &#1043; cirílico maiúsculo ghe
д &dcy; &#x00414; &#1044; cirílico maiúsculo de
е &iecy; &#x00415; &#1045; cirílico maiúsculo , ou seja
ж &zhcy; &#x00416; &#1046; cirílico maiúsculo zhe
з &zcy; &#x00417; &#1047; cirílico maiúsculo ze
и &icy; &#x00418; &#1048; cirílico maiúsculo i
й &jcy; &#x00419; &#1049; cirílico maiúsculo curto i
к &kcy; &#x0041a; &#1050; cirílico maiúsculo ka
л &lcy; &#x0041b; &#1051; cirílico maiúsculo el
м &mcy; &#x0041c; &#1052; cirílico maiúsculo em
н &ncy; &#x0041d; &#1053; cirílico maiúsculo en
о &ocy; &#x0041e; &#1054; cirílico maiúsculo o
п &pcy; &#x0041f; &#1055; cirílico maiúsculo pe
р &rcy; &#x00420; &#1056; cirílico maiúsculo
с &scy; &#x00421; &#1057; letras maiúsculas cirílicas
т &tcy; &#x00422; &#1058; cirílico maiúsculo te
у &ucy; &#x00423; &#1059; cirílico maiúsculo u
ф &fcy; &#x00424; &#1060; cirílico maiúsculo ef
х &khcy; &#x00425; &#1061; cirílico maiúsculo ha
ц &tscy; &#x00426; &#1062; cirílico maiúsculo tse
ч &chcy; &#x00427; &#1063; cirílico maiúsculo che
ш &shcy; &#x00428; &#1064; cirílico maiúsculo sha
щ &shchcy; &#x00429; &#1065; cirílico maiúsculo shcha
ъ &hardcy; &#x0042a; &#1066; cirílico maiúsculo
ы &ycy; &#x0042b; &#1067; cirílico maiúsculo yeru
ь &softcy; &#x0042c; &#1068; signo suave em cirílico maiúsculo
э &ecy; &#x0042d; &#1069; cirílico maiúsculo e
ю &yucy; &#x0042e; &#1070; cirílico maiúsculo yu
я &yacy; &#x0042f; &#1071; cirílico maiúsculo ya
а &acy; &#x00430; &#1072; cirílico minúsculo a
б &bcy; &#x00431; &#1073; cirílico minúsculo seja
в &vcy; &#x00432; &#1074; cirílico minúsculo ve
г &gcy; &#x00433; &#1075; cirílico minúsculo ghe
д &dcy; &#x00434; &#1076; cirílico minúsculo de
е &iecy; &#x00435; &#1077; cirílico minúsculo , isto é
ж &zhcy; &#x00436; &#1078; cirílico minúsculo zhe
з &zcy; &#x00437; &#1079; letra minúscula ze cirílica
и &icy; &#x00438; &#1080; cirílico minúsculo i
й &jcy; &#x00439; &#1081; cirílico minúsculo curta i
к &kcy; &#x0043a; &#1082; letra minúscula ka cirílica
л &lcy; &#x0043b; &#1083; letra minúscula el cirílica
м &mcy; &#x0043c; &#1084; em minúsculo cirílico
н &ncy; &#x0043d; &#1085; cirílico minúsculo en
о &ocy; &#x0043e; &#1086; minúsculo cirílico o
п &pcy; &#x0043f; &#1087; pe minúsculo cirílico
р &rcy; &#x00440; &#1088; cirílico minúsculo er
с &scy; &#x00441; &#1089; letras minúsculas cirílicas
т &tcy; &#x00442; &#1090; cirílico minúsculo te
у &ucy; &#x00443; &#1091; letra minúscula você em cirílico
ф &fcy; &#x00444; &#1092; cirílico minúsculo ef
х &khcy; &#x00445; &#1093; cirílico minúsculo ha
ц &tscy; &#x00446; &#1094; cirílico minúsculo tse
ч &chcy; &#x00447; &#1095; cirílico minúsculo che
ш &shcy; &#x00448; &#1096; letra minúscula em cirílico sha
щ &shchcy; &#x00449; &#1097; cirílico minúsculo shcha
ъ &hardcy; &#x0044a; &#1098; letra minúscula cirílico duro
ы &ycy; &#x0044b; &#1099; cirílico minúsculo yeru
ь &softcy; &#x0044c; &#1100; signo macio de letra minúscula cirílico
э &ecy; &#x0044d; &#1101; letra minúscula e cirílica
ю &yucy; &#x0044e; &#1102; letra minúscula em cirílico, você
я &yacy; &#x0044f; &#1103; cirílico minúsculo sim
ё &iocy; &#x00451; &#1105; cirílico minúsculo io
ђ &djcy; &#x00452; &#1106; dje cirílico minúsculo
ѓ &gjcy; &#x00453; &#1107; cirílico minúsculo gje
є &jukcy; &#x00454; &#1108; cirílico minúsculo ucraniana, ie
ѕ &dscy; &#x00455; &#1109; cirílico minúsculo dze
і &iukcy; &#x00456; &#1110; cirílico minúsculo bielorrussa-ucraniana i
ї &yicy; &#x00457; &#1111; letra minúscula em cirílico yi
ј &jsercy; &#x00458; &#1112; je minúsculo cirílico
љ &ljcy; &#x00459; &#1113; cirílico minúsculo lje
њ &njcy; &#x0045a; &#1114; nje minúsculo cirílico
ћ &tshcy; &#x0045b; &#1115; cirílico minúsculo tshe
ќ &kjcy; &#x0045c; &#1116; kje minúsculo cirílico
ў &ubrcy; &#x0045e; &#1118; cirílico minúsculo curta u
џ &dzcy; &#x0045f; &#1119; dzhe minúsculo cirílico
Miscelânia de Caracteres
Caracter HTML HEX DEC Descrição
&vzigzag; &#x0299a; &#10650; linha em ziguezague vertical
&vangrt; &#x0299c; &#10652; variante de ângulo reto com quadrado
&angrtvbd; &#x0299d; &#10653; ângulo reto medido com ponto
&ange; &#x029a4; &#10660; ângulo com barra
&range; &#x029a5; &#10661; ângulo invertido com barra inferior
&dwangle; &#x029a6; &#10662; ângulo oblíquo abrindo
&uwangle; &#x029a7; &#10663; abertura de ângulo oblíquo para baixo
&angmsdaa; &#x029a8; &#10664; medida de ângulo, seta nordeste
&angmsdab; &#x029a9; &#10665; medida de ângulo, seta oeste
&angmsdac; &#x029aa; &#10666; medida de ângulo, seta sudeste
&angmsdad; &#x029ab; &#10667; medida de ângulo, seta sudoeste
&angmsdae; &#x029ac; &#10668; medida de ângulo, seta nordeste
&angmsdaf; &#x029ad; &#10669; medida de ângulo, seta oeste
&angmsdag; &#x029ae; &#10670; medida de ângulo, seta sudeste
&angmsdah; &#x029af; &#10671; medida de ângulo, seta nordeste
&bemptyv; &#x029b0; &#10672; conjunto vazio invertido
&demptyv; &#x029b1; &#10673; conjunto vazio com barra superior
&cemptyv; &#x029b2; &#10674; conjunto vazio com círculo acima
&raemptyv; &#x029b3; &#10675; conjunto vazio com a seta direita acima
&laemptyv; &#x029b4; &#10676; conjunto vazio com seta esquerda acima
&ohbar; &#x029b5; &#10677; círculo com barra horizontal
&omid; &#x029b6; &#10678; barra vertical circulada
&opar; &#x029b7; &#10679; circulado paralelo
&operp; &#x029b9; &#10681; circular perpendicular
&olcross; &#x029bb; &#10683; círculo com x sobreposto
&odsold; &#x029bc; &#10684; divisão girado no sentido anti-horário
&olcir; &#x029be; &#10686; bala branca circulada
⦿ &ofcir; &#x029bf; &#10687; bala circulada
&olt; &#x029c0; &#10688; circulou menos que
&ogt; &#x029c1; &#10689; circulado maior que
&cirscir; &#x029c2; &#10690; círculo com círculo menor à direita
&cire; &#x029c3; &#10691; círculo com dois traços horizontais para a direita
&solb; &#x029c4; &#10692; barra diagonal ascendente quadrada
&bsolb; &#x029c5; &#10693; quadrado caindo barra diagonal
&boxbox; &#x029c9; &#10697; dois quadrados unidos
&trisb; &#x029cd; &#10701; triângulo com serifas na parte inferior
&rtriltri; &#x029ce; &#10702; triângulo direito acima do triângulo esquerdo
&lefttrianglebar; &#x029cf; &#10703; triângulo esquerdo ao lado da barra vertical
&righttrianglebar; &#x029d0; &#10704; barra vertical ao lado do triângulo retângulo
∽̱ &race; &#x029da; &#10714; cerca esquerda dupla ondulada
&eparsl; &#x029e3; &#10723; é igual a sinal e paralelo inclinado
&smeparsl; &#x029e4; &#10724; é igual ao sinal e inclinado paralelo ao til acima
&eqvparsl; &#x029e5; &#10725; idêntico e inclinado paralelo
&dsol; &#x029f6; &#10742; barra com traço superior
&pluscir; &#x02a22; &#10786; mais com ponto acima
&plusacir; &#x02a23; &#10787; mais com circunflexo acima
&simplus; &#x02a24; &#10788; mais com til acima
&plusdu; &#x02a25; &#10789; mais com ponto abaixo
&plussim; &#x02a26; &#10790; mais com til abaixo
&plustwo; &#x02a27; &#10791; mais com subscrito dois
&mcomma; &#x02a29; &#10793; menos com vírgula acima
&minusdu; &#x02a2a; &#10794; menos com ponto abaixo
&loplus; &#x02a2d; &#10797; mais no semicírculo esquerdo
&roplus; &#x02a2e; &#10798; mais no semicírculo direito
&cross; &#x02a2f; &#10799; vetor ou produto vetorial
&timesd; &#x02a30; &#10800; multiplicação com ponto acima
&timesbar; &#x02a31; &#10801; multiplicação com barra inferior
&smashp; &#x02a33; &#10803; esmagar produto
&lotimes; &#x02a34; &#10804; multiplicação no semicírculo esquerdo
&rotimes; &#x02a35; &#10805; multiplicação no semicírculo direito
&otimesas; &#x02a36; &#10806; multiplicação circulado com acento circunflexo
&otimes; &#x02a37; &#10807; multiplicação em círculo duplo
&odiv; &#x02a38; &#10808; divisão circulado
&triplus; &#x02a39; &#10809; mais no triângulo
&triminus; &#x02a3a; &#10810; menos no triângulo
&tritime; &#x02a3b; &#10811; multiplicação em triângulo
⨼ ⨼ &iprod; &intprod; &#x02a3c; &#10812; produto interior
⨿ &amalg; &#x02a3f; &#10815; amalgamação ou coproduto
&capdot; &#x02a40; &#10816; intersecção com ponto
&ncup; &#x02a42; &#10818; união com barra superior
&ncap; &#x02a43; &#10819; intersecção com barra superior
&capand; &#x02a44; &#10820; intersecção com lógica e
&cupor; &#x02a45; &#10821; união com lógica ou
&cupcap; &#x02a46; &#10822; união acima da interseção
&capcup; &#x02a47; &#10823; intersecção acima da união
&cupbrcap; &#x02a48; &#10824; união acima da barra acima da interseção
&capbrcup; &#x02a49; &#10825; intersecção acima da barra acima da união
&cupcup; &#x02a4a; &#10826; união ao lado e juntou-se a união
&capcap; &#x02a4b; &#10827; intersecção ao lado e junta com intersecção
&ccups; &#x02a4c; &#10828; união fechada com serifas
&ccaps; &#x02a4d; &#10829; interseção fechada com serifas
&ccupssm; &#x02a50; &#10832; união fechada com serifas e produto esmagado
&and; &#x02a53; &#10835; duplo lógico e
&or; &#x02a54; &#10836; duplo lógico ou
&andand; &#x02a55; &#10837; dois lógicos que se cruzam e
&oror; &#x02a56; &#10838; dois lógicos que se cruzam ou
&orslope; &#x02a57; &#10839; grande inclinado ou
&andslope; &#x02a58; &#10840; inclinado grande e
&andv; &#x02a5a; &#10842; lógico e com haste intermediária
&orv; &#x02a5b; &#10843; lógico ou com haste intermediária
&andd; &#x02a5c; &#10844; lógico e com traço horizontal
&ord; &#x02a5d; &#10845; lógico ou com traço horizontal
&wedbar; &#x02a5f; &#10847; lógico e com barra inferior
&sdote; &#x02a66; &#10854; é igual ao sinal com o ponto abaixo
&simdot; &#x02a6a; &#10858; Operador til com ponto acima
&congdot; &#x02a6d; &#10861; congruente com o ponto acima
&easter; &#x02a6e; &#10862; é igual a asterisco
&apacir; &#x02a6f; &#10863; quase igual a com acento circunflexo
&ape; &#x02a70; &#10864; aproximadamente igual ou igual a
&eplus; &#x02a71; &#10865; igual acima do mais
&pluse; &#x02a72; &#10866; mais acima do igual
&esim; &#x02a73; &#10867; igual ao sinal acima do operador til
&colone; &#x02a74; &#10868; dois pontos duplos iguais
&equal; &#x02a75; &#10869; dois sinais de igual consecutivos
&eddot; &ddotseq; &#x02a77; &#10871; é igual ao sinal com dois pontos acima e dois pontos abaixo
&equivdd; &equivdd; &#x02a78; &#10872; equivalente com quatro pontos acima
&ltcir; &#x02a79; &#10873; menos do que com um círculo dentro
&gtcir; &#x02a7a; &#10874; maior do que com um círculo dentro
&ltquest; &#x02a7b; &#10875; menos do que com ponto de interrogação acima
&gtquest; &#x02a7c; &#10876; maior do que com ponto de interrogação acima
&les; &lessslantequal; &leqslant; &#x02a7d; &#10877; menor ou inclinado igual a
&ges; &greaterslantequal; &geqslant; &#x02a7e; &#10878; maior que ou inclinado igual a
⩿ &lesdot; &#x02a7f; &#10879; menor que ou inclinado igual a com ponto dentro
&gesdot; &#x02a80; &#10880; maior que ou inclinado igual a com ponto dentro
&lesdoto; &#x02a81; &#10881; menor que ou inclinado igual ao ponto acima
&gesdoto; &#x02a82; &#10882; maior que ou inclinado igual ao ponto acima
&lesdotor; &#x02a83; &#10883; menor que ou inclinado igual a com ponto acima à direita
&gesdotol; &#x02a84; &#10884; maior que ou inclinado igual ao ponto acima à esquerda
&lap; &lessapprox; &#x02a85; &#10885; menor ou aproximado
&gap; &gtrapprox; &#x02a86; &#10886; maior que ou aproximado
&lne; &lneq; &#x02a87; &#10887; menor que e linha única não igual a
&gne; &gneq; &#x02a88; &#10888; maior que e linha única diferente de
&lnap; &lnapprox; &#x02a89; &#10889; inferior e não aproximado
&gnap; &gnapprox; &#x02a8a; &#10890; maior que e não aproximado
&leg; &lesseqqgtr; &#x02a8b; &#10891; menor que acima linha dupla igual acima maior que
&gel; &gtreqqless; &#x02a8c; &#10892; maior que acima linha dupla igual acima menor que
&lsime; &#x02a8d; &#10893; menor que acima semelhante ou igual
&gsime; &#x02a8e; &#10894; maior do que acima semelhante ou igual
&lsimg; &#x02a8f; &#10895; menor que acima semelhante acima maior que
&gsiml; &#x02a90; &#10896; maior que acima semelhante acima menor que
&lge; &lge; &#x02a91; &#10897; menor que acima maior que acima linha dupla igual
&gle; &gle; &#x02a92; &#10898; maior que acima menor que acima linha dupla igual
&lesges; &#x02a93; &#10899; menor que acima inclinado igual acima maior que acima inclinado igual
&gesles; &#x02a94; &#10900; maior que acima inclinado igual acima menor que acima inclinado igual
&els; &eqslantless; &#x02a95; &#10901; inclinado igual ou menor que
&egs; &eqslantgtr; &#x02a96; &#10902; inclinado igual ou maior que
&elsdot; &#x02a97; &#10903; inclinado igual ou menor do que com ponto dentro
&egsdot; &#x02a98; &#10904; inclinado igual ou maior que com ponto dentro
&el; &#x02a99; &#10905; linha dupla igual ou menor que
&eg; &#x02a9a; &#10906; linha dupla igual ou maior que
&siml; &#x02a9d; &#10909; semelhante ou inferior
&simg; &#x02a9e; &#10910; semelhante ou maior que
&simle; &simle; &#x02a9f; &#10911; semelhante acima menos-que acima é igual ao sinal
&simge; &simge; &#x02aa0; &#10912; semelhante acima maior do que acima é igual ao sinal
&lessless; &lessless; &#x02aa1; &#10913; duplo aninhado menor que
&greatergreater; &greatergreater; &#x02aa2; &#10914; aninhado duplo maior que
&glj; &#x02aa4; &#10916; maior que sobreposição menor que
&gla; &#x02aa5; &#10917; maior que ao lado menor que
&ltcc; &#x02aa6; &#10918; menos que fechado por curva
&gtcc; &#x02aa7; &#10919; maior que fechado por curva
&lescc; &#x02aa8; &#10920; menos que fechado pela curva acima inclinado igual
&gescc; &#x02aa9; &#10921; maior que fechado por curva acima inclinado igual
&smt; &#x02aaa; &#10922; menor que
&lat; &#x02aab; &#10923; maior que
&smte; &#x02aac; &#10924; menor ou igual a
&late; &#x02aad; &#10925; maior ou igual a
&bumpe; &#x02aae; &#10926; é igual ao sinal com irregular acima
&pre; &preceq; &precedesequal; &#x02aaf; &#10927; precede acima do igual de linha única
&sce; &succeq; &succeedsequal; &#x02ab0; &#10928; sucede acima do igual de linha única
&pre; &#x02ab3; &#10931; precede o igual
&sce; &#x02ab4; &#10932; sucede acima do igual
&prne; &precneqq; &#x02ab5; &#10933; precede acima não é igual a
&scne; &succneqq; &#x02ab6; &#10934; sucede acima não igual a
&prap; &precapprox; &#x02ab7; &#10935; precede acima quase igual a
&scap; &succapprox; &#x02ab8; &#10936; sucede acima de quase igual a
&prnap; &precnapprox; &#x02ab9; &#10937; precede acima, não quase igual a
&scnap; &succnapprox; &#x02aba; &#10938; sucede acima, não quase igual a
&pr; &#x02abb; &#10939; o dobro precede
&sc; &#x02abc; &#10940; sucesso duplo
&subdot; &#x02abd; &#10941; subconjunto com ponto
&supdot; &#x02abe; &#10942; superconjunto com ponto
⪿ &subplus; &#x02abf; &#10943; subconjunto com mais abaixo
&supplus; &#x02ac0; &#10944; superconjunto com mais abaixo
&submult; &#x02ac1; &#10945; subconjunto com multiplicação abaixo
&supmult; &#x02ac2; &#10946; superconjunto com multiplicação abaixo
&subedot; &#x02ac3; &#10947; subconjunto de ou igual a com ponto acima
&supedot; &#x02ac4; &#10948; superconjunto de ou igual a com ponto acima
&sube; &subseteqq; &#x02ac5; &#10949; subconjunto de igual acima
&supe; &supseteqq; &#x02ac6; &#10950; superconjunto de igual acima
&subsim; &#x02ac7; &#10951; subconjunto do operador til acima
&supsim; &#x02ac8; &#10952; superconjunto do operador til acima
&subne; &subsetneqq; &#x02acb; &#10955; subconjunto de acima não igual a
&supne; &supsetneqq; &#x02acc; &#10956; superconjunto de acima não igual a
&csub; &#x02acf; &#10959; subconjunto fechado
&csup; &#x02ad0; &#10960; superconjunto fechado
&csube; &#x02ad1; &#10961; subconjunto fechado ou igual a
&csupe; &#x02ad2; &#10962; superconjunto fechado ou igual a
&subsup; &#x02ad3; &#10963; subconjunto acima do superconjunto
&supsub; &#x02ad4; &#10964; superconjunto acima do subconjunto
&subsub; &#x02ad5; &#10965; subconjunto acima do subconjunto
&supsup; &#x02ad6; &#10966; superconjunto acima do superconjunto
&suphsub; &#x02ad7; &#10967; superconjunto ao lado do subconjunto
&supdsub; &#x02ad8; &#10968; superconjunto ao lado e unido por traço com subconjunto
&forkv; &#x02ad9; &#10969; elemento de abertura para baixo
&topfork; &#x02ada; &#10970; forcado com camiseta
&mlcp; &#x02adb; &#10971; intersecção transversal
&dashv; &doublelefttee; &#x02ae4; &#10980; barra vertical dupla catraca esquerda
&vdashl; &#x02ae6; &#10982; traço longo do membro esquerdo da vertical dupla
&barv; &#x02ae7; &#10983; amura curta com barra superior
&vbar; &#x02ae8; &#10984; amura curta com barra inferior
&vbarv; &#x02ae9; &#10985; amura curta acima da amura curta
&vbar; &#x02aeb; &#10987; dobrar a aderência
¬ &not; &#x02aec; &#10988; traço duplo não sinal
&bnot; &#x02aed; &#10989; traço duplo invertido sem sinal
&rnmid; &#x02aee; &#10990; não divide com barra de negação invertida
&cirmid; &#x02aef; &#10991; linha vertical com círculo acima
&midcir; &#x02af0; &#10992; linha vertical com círculo abaixo
&topcir; &#x02af1; &#10993; rumo para baixo com círculo abaixo
&nhpar; &#x02af2; &#10994; paralelo com traço horizontal
&parsim; &#x02af3; &#10995; paralelo com operador til
&parsl; &#x02afd; &#11005; operador barra dupla
Sinais Gráficos
Caracter HTML HEX DEC Descrição
&dagger; &#x02020; &#8224; punhal
&dagger; &ddagger; &#x02021; &#8225; punhal duplo
&bull; &bullet; &#x02022; &#8226; bala
&nldr; &#x02025; &#8229; líder de dois pontos
&hellip; &mldr; &#x02026; &#8230; elipse horizontal
&permil; &#x02030; &#8240; por milhar
&pertenk; &#x02031; &#8241; por dez mil
&prime; &#x02032; &#8242; aspas
&prime; &#x02033; &#8243; aspas dupla
&tprime; &#x02034; &#8244; aspas tripla
&qprime; &#x02057; &#8279; aspas quádruplas
&bprime; &backprime; &#x02035; &#8245; aspas invertida
&lsaquo; &#x02039; &#8249; única aspa angular esquerda
&rsaquo; &#x0203a; &#8250; única aspa angular direita
&oline; &#x0203e; &#8254; overline
&caret; &#x02041; &#8257; ponto de inserção acento circunflexo
&hybull; &#x02043; &#8259; hífen marcador
&frasl; &#x02044; &#8260; barra de fração
&bsemi; &#x0204f; &#8271; ponto e vírgula invertido
&applyfunction; &af; &#x02061; &#8289; aplicação de função
&tdot; &tripledot; &#x020db; &#8411; combinando três pontos acima
𝕔 &copf; &complexes; &#x02102; &#8450; c maiúsculo duplo
&incare; &#x02105; &#8453; aos cuidados de
&gscr; &#x0210a; &#8458; script g minúsculo
&hamilt; &hilbertspace; &hscr; &#x0210b; &#8459; script h maiúsculo
𝔥 &hfr; &poincareplane; &#x0210c; &#8460; letra preta h maiúsculo
𝕙 &quaternions; &hopf; &#x0210d; &#8461; H maiúsculo duplo
&planckh; &#x0210e; &#8462; constante de planck
&planck; &hbar; &plankv; &hslash; &#x0210f; &#8463; Planck cortado
&iscr; &imagline; &#x02110; &#8464; script I maiúsculo
&image; &im; &imagpart; &ifr; &#x02111; &#8465; letra preta i maiúscula
&lscr; &lagran; &laplacetrf; &#x02112; &#8466; script l maiúsculo
&ell; &#x02113; &#8467; roteiro pequeno l
𝕟 ℕ &nopf; &naturals; &#x02115; &#8469; n maiúsculo duplo
&numero; &#x02116; &#8470; sinal numero
&copysr; &#x02117; &#8471; gravação de som copyright
&weierp; &wp; &#x02118; &#8472; script p
𝕡 ℙ &popf; &primes; &#x02119; &#8473; p maiúsculo duplo
ℚ 𝕢 &rationals; &qopf; &#x0211a; &#8474; Q maiúsculo duplo
&rscr; &realine; &#x0211b; &#8475; script r maiúsculo
ℜ 𝔯 &real; &re; &realpart; &rfr; &#x0211c; &#8476; reais
ℝ 𝕣 &reals; &ropf; &#x0211d; &#8477; r maiúsculo duplo
&rx; &#x0211e; &#8478; receita
&trade; &trade; &#x02122; &#8482; marca registrada
&integers; &zopf; &#x02124; &#8484; z maiúsculo duplo
Ω &ohm; &#x02126; &#8486; ohm (resistência)
&mho; &#x02127; &#8487; ohm invertido
𝔷 ℨ &zfr; &zeetrf; &#x02128; &#8488; preta z maiúscula
&iiota; &#x02129; &#8489; minúsculo iota
Å &angst; &#x0212b; &#8491; angstrom
&bernou; &bernoullis; &#x0212c; &#8492; script b maiúsculo
𝔠 &cfr; &cayleys; &#x0212d; &#8493; letra preta c maiúscula
&escr; &#x0212f; &#8495; script e pequeno
&escr; &expectation; &#x02130; &#8496; script e maiúsculo
𝒻 &fscr; &fouriertrf; &#x02131; &#8497; script f maiúsculo
ℳ 𝓂 &phmmat; &mellintrf; &mscr; &#x02133; &#8499; script m
&order; &orderof; &oscr; &#x02134; &#8500; script pequeno o
ℵ ℵ &alefsym; &aleph; &#x02135; &#8501; símbolo alef
&beth; &#x02136; &#8502; símbolo de aposta
&gimel; &#x02137; &#8503; símbolo gimel
&daleth; &#x02138; &#8504; símbolo dalet
&dD; &#x02145; &#8517; itálico duplo traçado d
&dd; &#x02146; &#8518; itálico duplo traçado pequeno d
&exponentiale; &exponentiale; &ee; &#x02147; &#8519; e pequeno itálico duplo traçado
&imaginaryi; &ii; &#x02148; &#8520; itálico duplo traçado pequeno i
&prop; &propto; &vprop; &#x0221d; &#8733; proporcional a
&infin; &#x0221e; &#8734; infinito
&angrt; &#x0221f; &#8735; ângulo reto
&ang; &#x02220; &#8736; ângulo
&angmsd; &measuredangle; &#x02221; &#8737; ângulo medido
&angsph; &#x02222; &#8738; ângulo esférico
&mid; &smid; &shortmid; &#x02223; &#8739; divide
&nmid; &nsmid; &nshortmid; &#x02224; &#8740; não divide
&par; &parallel; &spar; &#x02225; &#8741; paralelo a
&npar; &nparallel; &#x02226; &#8742; não paralelo a
&and; &wedge; &#x02227; &#8743; lógico e
&or; &vee; &#x02228; &#8744; lógico ou
&cap; &#x02229; &#8745; interseção
&cup; &#x0222a; &#8746; união
&there4; &therefore; &therefore; &#x02234; &#8756; portanto
&becaus; &because; &because; &#x02235; &#8757; porque
&ratio; &#x02236; &#8758; razão
: &colon; &proportion; &#x02237; &#8759; proporção
&minusd; &dotminus; &#x02238; &#8760; ponto menos
&homtht; &#x0223b; &#8763; homotético
&sim; &thksim; &thicksim; &#x0223c; &#8764; operador til
&bsim; &backsim; &#x0223d; &#8765; til invertido
&ac; &mstpos; &#x0223e; &#8766; S invertido
&acd; &#x0223f; &#8767; senoidal
&wreath; &verticaltilde; &wr; &#x02240; &#8768; produto de coroa
&nsim; &nottilde; &#x02241; &#8769; til cortado
&esim; &equaltilde; &eqsim; &#x02242; &#8770; menos til
&sime; &tildeequal; &simeq; &#x02243; &#8771; assintoticamente igual a
&nsime; &nsimeq; &nottildeequal; &#x02244; &#8772; não assintoticamente igual a
&cong; &tildefullequal; &#x02245; &#8773; aproximadamente igual a
&simne; &#x02246; &#8774; aproximadamente, mas não exatamente igual
&ncong; &nottildefullequal; &#x02247; &#8775; nem aproximado nem igual a
&asymp; &ap; &approx; &thkap; &thickapprox; &#x02248; &#8776; quase igual
&nap; &nottildetilde; &napprox; &#x02249; &#8777; não quase igual
&ape; &approxeq; &#x0224a; &#8778; quase igual ou igual
&apid; &#x0224b; &#8779; triplo till
&bcong; &backcong; &#x0224c; &#8780; todos iguais a
&asympeq; &cupcap; &#x0224d; &#8781; equivalente a
&bump; &humpdownhump; &bumpeq; &#x0224e; &#8782; geometricamente equivalente a
&bumpe; &humpequal; &bumpeq; &#x0224f; &#8783; diferença entre
&esdot; &dotequal; &doteq; &#x02250; &#8784; aproxima-se do limite
ė &edot; &doteqdot; &#x02251; &#8785; geometricamente igual a
&colone; &coloneq; &#x02254; &#8788; dois pontos igual
&ecolon; &eqcolon; &#x02255; &#8789; igual dois pontos
&ecir; &eqcirc; &#x02256; &#8790; anel igual a
&cire; &circeq; &#x02257; &#8791; anel igual a
&wedgeq; &#x02259; &#8793; estimativas
&veeeq; &#x0225a; &#8794; equiangular para
&trie; &triangleq; &#x0225c; &#8796; delta igual
&equest; &questeq; &#x0225f; &#8799; igual questionado
&ne; &notequal; &#x02260; &#8800; não é igual a (diferente)
&equiv; &congruent; &#x02261; &#8801; idêntico a
&nequiv; &notcongruent; &#x02262; &#8802; não idêntico a
&le; &leq; &#x02264; &#8804; menor ou igual
&ge; &greaterequal; &geq; &#x02265; &#8805; maior ou igual
&le; &lessfullequal; &leqq; &#x02266; &#8806; menor que, igual
&ge; &greaterfullequal; &geqq; &#x02267; &#8807; maior do, igual
&lne; &lneqq; &#x02268; &#8808; menor que, diferente
&gne; &gneqq; &#x02269; &#8809; maior que, diferente
< &lt; &nestedlessless; &ll; &#x0226a; &#8810; muito menor que
> &gt; &nestedgreatergreater; &gg; &#x0226b; &#8811; muito maior que
&twixt; &between; &#x0226c; &#8812; entre
&nlt; &notless; &nless; &#x0226e; &#8814; não menor que
&ngt; &notgreater; &ngtr; &#x0226f; &#8815; não maior que
&nle; &notlessequal; &nleq; &#x02270; &#8816; nem menor que nem igual a
&nge; &notgreaterequal; &ngeq; &#x02271; &#8817; nem maior que nem igual a
&lsim; &lesstilde; &lesssim; &#x02272; &#8818; menor ou equivalente a
&gsim; &gtrsim; &greatertilde; &#x02273; &#8819; maior que ou equivalente a
&nlsim; &notlesstilde; &#x02274; &#8820; nem menor que nem equivalente a
&ngsim; &notgreatertilde; &#x02275; &#8821; nem maior que nem equivalente a
&lg; &lessgtr; &lessgreater; &#x02276; &#8822; menor ou maior que
&gl; &gtrless; &greaterless; &#x02277; &#8823; maior ou menor que
&ntlg; &notlessgreater; &#x02278; &#8824; nem menor que nem maior que
&ntgl; &notgreaterless; &#x02279; &#8825; nem maior que nem menor que
&pr; &precedes; &prec; &#x0227a; &#8826; precede
&sc; &succeeds; &succ; &#x0227b; &#8827; sucede
&prcue; &precedesslantequal; &preccurlyeq; &#x0227c; &#8828; precede ou igual a
&sccue; &succeedsslantequal; &succcurlyeq; &#x0227d; &#8829; sucede ou igual
&prsim; &precsim; &precedestilde; &#x0227e; &#8830; precede ou equivalente a
&scsim; &succsim; &succeedstilde; &#x0227f; &#8831; sucede ou equivalente a
&npr; &nprec; &notprecedes; &#x02280; &#8832; não precede
&nsc; &nsucc; &notsucceeds; &#x02281; &#8833; não sucede
&sqsub; &squaresubset; &sqsubset; &#x0228f; &#8847; imagem quadrada de
&sqsup; &squaresuperset; &sqsupset; &#x02290; &#8848; quadrado original de
&sqsube; &squaresubsetequal; &sqsubseteq; &#x02291; &#8849; imagem quadrada de ou igual a
&sqsupe; &squaresupersetequal; &sqsupseteq; &#x02292; &#8850; quadrado original de ou igual a
&sqcap; &squareintersection; &#x02293; &#8851; chapeu quadrado
&sqcup; &squareunion; &#x02294; &#8852; copo quadrado
&vdash; &righttee; &#x022a2; &#8866; rumo direito
&dashv; &lefttee; &#x022a3; &#8867; rumo esquerdo
&top; &downtee; &#x022a4; &#8868; aderência
&bottom; &bot; &perp; &uptee; &#x022a5; &#8869; aderência
&models; &#x022a7; &#8871; modela
&vdash; &doublerighttee; &#x022a8; &#8872; verdadeiro
&vdash; &#x022a9; &#8873; forças
&vdash; &#x022ab; &#8875; barra vertical dupla catraca direita dupla
&nvdash; &#x022ac; &#8876; não prova
&nvdash; &#x022ad; &#8877; Não é verdade
&nvdash; &#x022ae; &#8878; não força
&nvdash; &#x022af; &#8879; torniquete duplo direito barra vertical dupla negada
&prurel; &#x022b0; &#8880; precede em relação
&vltri; &vartriangleleft; &lefttriangle; &#x022b2; &#8882; subgrupo normal de
&vrtri; &vartriangleright; &righttriangle; &#x022b3; &#8883; contém como subgrupo normal
&ltrie; &trianglelefteq; &lefttriangleequal; &#x022b4; &#8884; subgrupo normal ou igual a
&rtrie; &trianglerighteq; &righttriangleequal; &#x022b5; &#8885; contém como subgrupo normal ou igual a
&origof; &#x022b6; &#8886; original de
&imof; &#x022b7; &#8887; imagem de
&mumap; &multimap; &#x022b8; &#8888; multimapa
&hercon; &#x022b9; &#8889; matriz conjugada hermitiana
&intcal; &intercal; &#x022ba; &#8890; intercalar
&veebar; &#x022bb; &#8891; xor lógico
&barvee; &#x022bd; &#8893; nor lógico
&angrtvb; &#x022be; &#8894; ângulo reto com arco
&lrtri; &#x022bf; &#8895; triângulo retângulo
&xwedge; &wedge; &bigwedge; &#x022c0; &#8896; n-ário lógico e
&xvee; &vee; &bigvee; &#x022c1; &#8897; n-ário lógico ou
&diam; &diamond; &diamond; &#x022c4; &#8900; operador de diamante
&sdot; &#x022c5; &#8901; operador de ponto
&sstarf; &star; &#x022c6; &#8902; operador estrela
&divonx; &divideontimes; &#x022c7; &#8903; vezes divisão
&bowtie; &#x022c8; &#8904; gravata-borboleta
&ltimes; &#x022c9; &#8905; produto semidireto de fator normal esquerdo
&rtimes; &#x022ca; &#8906; produto semidireto de fator normal correto
&lthree; &leftthreetimes; &#x022cb; &#8907; produto semidireto esquerdo
&rthree; &rightthreetimes; &#x022cc; &#8908; produto semidireto certo
&bsime; &backsimeq; &#x022cd; &#8909; til invertido é igual a
&cuvee; &curlyvee; &#x022ce; &#8910; ou lógico curvo
&cuwed; &curlywedge; &#x022cf; &#8911; e lógico curvo
&sub; &subset; &#x022d0; &#8912; subconjunto duplo
&sup; &supset; &#x022d1; &#8913; superconjunto duplo
&cap; &#x022d2; &#8914; cruzamento duplo
&cup; &#x022d3; &#8915; união dupla
&fork; &pitchfork; &#x022d4; &#8916; forquilha
&epar; &#x022d5; &#8917; igual e paralelo a
&ltdot; &lessdot; &#x022d6; &#8918; menos do que com ponto
&gtdot; &gtrdot; &#x022d7; &#8919; maior do que com ponto
&ll; &#x022d8; &#8920; muito menos do que
&gg; &ggg; &#x022d9; &#8921; muito maior do que
&leg; &lessequalgreater; &lesseqgtr; &#x022da; &#8922; menor que igual ou maior que
&gel; &gtreqless; &greaterequalless; &#x022db; &#8923; maior que igual ou menor que
&cuepr; &curlyeqprec; &#x022de; &#8926; igual a ou precede
&cuesc; &curlyeqsucc; &#x022df; &#8927; igual ou sucede
&nprcue; &notprecedesslantequal; &#x022e0; &#8928; não precede ou é igual
&nsccue; &notsucceedsslantequal; &#x022e1; &#8929; não sucede ou igual
&nsqsube; &notsquaresubsetequal; &#x022e2; &#8930; imagem não quadrada ou igual a
&nsqsupe; &notsquaresupersetequal; &#x022e3; &#8931; não quadrado original ou igual a
&lnsim; &#x022e6; &#8934; menor que, mas não equivalente a
&gnsim; &#x022e7; &#8935; maior que, mas não equivalente a
&prnsim; &precnsim; &#x022e8; &#8936; precede, mas não é equivalente a
&scnsim; &succnsim; &#x022e9; &#8937; sucede, mas não equivalente a
&nltri; &ntriangleleft; &notlefttriangle; &#x022ea; &#8938; subgrupo não normal de
&nrtri; &ntriangleright; &notrighttriangle; &#x022eb; &#8939; não contém um subgrupo normal
&nltrie; &ntrianglelefteq; &notlefttriangleequal; &#x022ec; &#8940; subgrupo não normal ou igual a
&nrtrie; &ntrianglerighteq; &notrighttriangleequal; &#x022ed; &#8941; não contém subgrupo normal ou igual
&vellip; &#x022ee; &#8942; elipse vertical
&ctdot; &#x022ef; &#8943; elipse horizontal da linha média
&utdot; &#x022f0; &#8944; elipse diagonal direita
&dtdot; &#x022f1; &#8945; elipse diagonal direita para baixo
&disin; &#x022f2; &#8946; elemento de com longo curso horizontal
&isinsv; &#x022f3; &#8947; elemento de com barra vertical no final do curso horizontal
&isins; &#x022f4; &#8948; pequeno elemento de com barra vertical no final do traço horizontal
&isindot; &#x022f5; &#8949; elemento de com ponto acima
&notinvc; &#x022f6; &#8950; elemento de com barra superior
&notinvb; &#x022f7; &#8951; pequeno elemento de com barra superior
&nisd; &#x022fa; &#8954; contém com longo curso horizontal
&xnis; &#x022fb; &#8955; contém com barra vertical no final do traço horizontal
&nis; &#x022fc; &#8956; pequeno contém com barra vertical no final do traço horizontal
&notnivc; &#x022fd; &#8957; contém com barra superior
&notnivb; &#x022fe; &#8958; pequeno contém com barra superior
&barwed; &barwedge; &#x02305; &#8965; projetivo
&barwed; &doublebarwedge; &#x02306; &#8966; perspectiva
&lceil; &leftceiling; &#x02308; &#8968; teto esquerdo
&rceil; &rightceiling; &#x02309; &#8969; teto direito
&lfloor; &leftfloor; &#x0230a; &#8970; chão esquerdo
&rfloor; &rightfloor; &#x0230b; &#8971; chão certo
&drcrop; &#x0230c; &#8972; corte inferior direito
&dlcrop; &#x0230d; &#8973; corte inferior esquerdo
&urcrop; &#x0230e; &#8974; corte superior direito
&ulcrop; &#x0230f; &#8975; corte superior esquerdo
&bnot; &#x02310; &#8976; invertido, não assinar
&profline; &#x02312; &#8978; arco
&profsurf; &#x02313; &#8979; segmento
&telrec; &#x02315; &#8981; gravador de telefone
&target; &#x02316; &#8982; indicador de posição
&ulcorn; &ulcorner; &#x0231c; &#8988; canto superior esquerdo
&urcorn; &urcorner; &#x0231d; &#8989; canto superior direito
&dlcorn; &llcorner; &#x0231e; &#8990; canto inferior esquerdo
&drcorn; &lrcorner; &#x0231f; &#8991; canto inferior direito
&frown; &sfrown; &#x02322; &#8994; carranca
&smile; &ssmile; &#x02323; &#8995; sorriso
&cylcty; &#x0232d; &#9005; cilindricidade
&profalar; &#x0232e; &#9006; perfil generalizado
&topbot; &#x02336; &#9014; símbolo funcional apl i-beam
&ovbar; &#x0233d; &#9021; estilo de círculo de símbolo funcional apl
&solbar; &#x0233f; &#9023; barra de barra de símbolo funcional apl
&angzarr; &#x0237c; &#9084; ângulo reto com seta em zigue-zague para baixo
&lmoust; &lmoustache; &#x023b0; &#9136; seção superior esquerda ou inferior direita das chaves
&rmoust; &rmoustache; &#x023b1; &#9137; seção superior direita ou inferior esquerda das chaves
&tbrk; &overbracket; &#x023b4; &#9140; colchete superior
&bbrk; &underbracket; &#x023b5; &#9141; colchete inferior
&bbrktbrk; &#x023b6; &#9142; colchete inferior sobre colchete superior
&trpezium; &#x023e2; &#9186; trapézio branco

Tabela ASCII

Linguagem de Consulta SQL

Definições

Banco de dados relacional é um banco de dados digital baseado no modelo relacional proposto por E. F. Codd em 1970. Sistema de software usados para construir e manter bancos de dados relacionais são chamados Sistema de Gerenciamento de Banco de Dados Relacionais (RDBMS).

SQL, (Structured Query Language) ou Linguagem de Consultas Estruturada é uma linguagem de programação usada para manipular de bancos de dados relacionais. Usando SQL é possível construir o BD, estabelecer relações entre dados nas tabelas, fazer consultas, inserir, apagar ou editar dados.

Um banco de dados consiste em várias tabelas e das relações predefinidas entre elas. Cada tabela contém colunas ou campos, cada uma delas com seu nome exclusivo e tipos de dados definido. Elas podem ter atributos que definem a funcionalidade da coluna (se é uma chave primária, se há um valor default, etc.). As linhas da tabela, ou registros, contêm os dados.

Para que serve a SQL?

Consultas SQL podem ser feitas dentro de diversos aplicativos tais como em suites MS Office, em particular no MS Access, e seus equivalentes open source. Elas também são frequentes em programas de gerenciamento de banco de dados, Business Inteligence e análises de dados tais como Qlikview e MS PowerBI. A maior parte dos sistemas de gerenciamento de conteúdo usados em sites na Internet, como WordPress e Joomla usam bancos de dados controlados por SQL.

As diversas linguagens de programação fornecem interfaces com as diversas variantes de bancos de dados SQL. Finalmente você pode instalar um Sistema Gerenciador de Banco de Dados (DBMS) em seu computador, seja ele um servidor ou sua desktop pessoal. Estes sistemas estão disponíveis em diversos sistemas operacionais. Os DBMS mais populares são: SQLite, MySQL, PostgreSQL, LibreOffice Base (todos eles open source) e Microsoft Access, SQL Server, FileMaker, Oracle (proprietários).

Comandos e instruções do SQL

Uma escola pode manter um banco de dados com informações sobre alunos, professores, funcionários, disciplinas lecionadas, salas de aulas, e a descrição de relacionamentos entre eles. Segue um exemplo simples de uma tabela de em banco de dados contendo o dados (simplificados e fictícios) de alunos. A primeira linha, listada em negrito, contém os nomes das colunas da tabela:

Tabela (1): Alunos
Matricula Nome Sobrenome email Nascimento Fone
734236 João Santos joao@yahoo.com 02-04-1998 61 123455667
789234 George Pereira george@gmail.com 04-04-2000 41 345678987
654987 Paula Torres ptorres@globo.com 25-01-2004 31 987854543
765098 Marcos Melo mamelo@gmail.com 25-10-2004 31 987843231

Nessa tabela Matricula é um campo numérico, Nome, Sobrenome, email e Fone são campos de strings, Nascimento é um campo de datas.

SELECT

A instrução SELECT é usada para recuperar (ler e retornar) dados de uma tabela. Ela tem a seguinte sintaxe geral:

SELECT Coluna1, ..., Colunan FROM Tabela1
SELECT * FROM Tabela1

A primeira linha retorna todos os registros da Tabela1, da Coluna1, …, Colunan, sem qualquer critério de seleção. A segunda retorna todos os campos da Tabela1 (* substitui a lista de todos os campos). A declaração explícita de quais campos se quer usar torna a consulta mais eficiente (rápida).

Por exemplo:

-- Para retornar todos os Nomes e Sobrenomes da tabela
SELECT Nome, Sobrenome FROM Alunos
Tabela (2):
Nome Sobrenome
João Santos
George Pereira
Paula Torres
Marcos Melo

O sinal -- inicia um comentário em SQL, uma parte da instrução que será ignorada. Comandos SQL podem ser em maiúsculas ou minúscula, embora seja costume usar letras maiúsculas.

Cláusula WHERE

A Cláusula WHERE é uma modificação da consulta com SELECT especificando condições de retorno. Ela restringe os dados retornados para apenas aqueles satisfeitos pela cláusula. Por exemplo, supondo que o campo matrícula seja numérico:

SELECT Nome, Sobrenome, email FROM Alunos WHERE Matricula = 654987

retorna

Tabela (3):
Nome Sobrenome email
Paula Torres ptorres@globo.com

Ou

SELECT Matricula, email FROM Alunos WHERE Nome = 'Marcos'

retorna

Tabela (4):
Matricula email
765098 mamelo@gmail.com

Os seguintes operadores de comparação podem ser usados com WHERE: = (igual, usado acima), <> (diferente),
> (maior que), >= (maior ou igual), < (menor que), =< (menor ou igual),
LIKE (similar), BETWEEN (define uma faixa).

SELECT Matricula, Nome, Sobrenome FROM Alunos WHERE Matricula > 740000
Tabela (5):
Matricula Nome Sobrenome
789234 George Pereira
765098 Marcos Melo
SELECT Matricula, Nome, Sobrenome FROM Alunos WHERE Nascimento <> '25-01-2004'
Tabela (6):
Matricula Nome Sobrenome
734236 João Santos
789234 George Pereira

O mesmo procedimento é usado para os demais operadores.

O Operador LIKE pode ser usado junto com %, um wildcard ou coringa que representa qualquer string (um ou mais caracteres). Ele pode ser posto em qualquer lugar, quantas vezes for necessário.

SELECT * FROM Alunos WHERE Nome LIKE 'PA%'
-- Nomes que começam com 'PA'
Tabela (7):
Matricula Nome Sobrenome email Nascimento Fone
654987 Paula Torres ptorres@globo.com 25-01-2004 31 987854543

O Operador BETWEEN possui sintaxe um pouco diferente para cada RDBMS. Em geral é algo do tipo:

SELECT * FROM Alunos WHERE Nascimento BETWEEN '01-01-2002' AND '01-01-2005'
-- Nascidos no intervalo
Tabela (8):
Matricula Nome Sobrenome email Nascimento Fone
654987 Paula Torres ptorres@globo.com 25-01-2004 31 987854543
765098 Marcos Melo mamelo@gmail.com 25-01-2004 31 987843231

O coringa _ representa um único caracter e [] uma faixa de valores. Por exemplo, a consulta seguinte retorna todos os registros onde Fone começa com 3, 4, 5 ou 6 e tem qualquer segundo dígito. No caso de nossa tabela Alunos seriam todos os registros.

SELECT * FROM Alunos WHERE Fone LIKE '[3-6]_%'

SELECT DISTINCT

Se você quiser obter valores únicos de uma tabela, sem repetições, use a cláusula DISTINCT.

SELECT DISTINCT Nascimento FROM Alunos 
Tabela (9):
Nascimento
02-04-1998
04-04-2000
25-01-2004

ORDER BY

A cláusula ORDER BY é usada junto com SELECT para ordenar os resultados de uma consulta. Ela tem a seguinte sintaxe geral:

SELECT campo1, ..., campon FROM Tabela1 ORDER BY (lista de campos)

Por exemplo:

-- Para retornar todos os Nomes e Sobrenomes da tabela, em ordem de Nome
SELECT Nome, Sobrenome FROM Alunos ORDER BY Nome
Tabela (10):
Nome Sobrenome
George Pereira
João Santos
Marcos Melo
Paula Torres

ORDER BY pode ser usada com os modificadores ASC ou DESC, para produzir a lista em ordem crescente ou descendente. ASC é o default e não precisa ser especificado. Para obter a mesma lista anterior em ordem descendente no sobrenome:

-- Para retornar todos os Nomes e Sobrenomes da tabela, em ordem de Nome
SELECT Nome, Sobrenome FROM Alunos ORDER BY Sobrenome DESC
Tabela (11):
Nome Sobrenome
Paula Torres
João Santos
George Pereira
Marcos Melo

TOP

A cláusula TOP é usada junto com SELECT e, geralmente com ORDER BY para selecionar apenas um número fixo de resultados retornados por uma consulta. Ela tem a seguinte sintaxe geral:

SELECT TOP número| % campo1, ..., campon FROM Tabela1 ORDER BY (lista de campos)

Por exemplo:

-- Para retornar os dois últimos Nomes da tabela, em ordem de Nome
SELECT TOP 2 Nome, Sobrenome FROM Alunos ORDER BY Nome DESC
Tabela (12):
Nome Sobrenome
Paula Torres
Marcos Melo

Para ver 10% dos primeiros registros de uma lista podemos usar:

SELECT TOP 10% * FROM Tabela ORDER BY campo

Operadores lógicos AND e OR

Mais de uma condição podem ser anexadas à cláusula WHERE usando os operadores AND e OR.

SELECT * FROM Alunos WHERE Matricula > 700000 AND Fone LIKE '31%'
Tabela (13):
Matricula Nome Sobrenome email Nascimento Fone
765098 Marcos Melo mamelo@gmail.com 25-10-2004 31 987843231
SELECT * FROM Alunos WHERE Matricula > 700000 OR Sobrenome = 'Torres'

Na última consulta todos os registros serial retornados.

Condições mais complexas podem ser expressas usando-se parênteses.

SELECT Matricula, Nome, Sobrenome FROM Alunos
   WHERE (Nome = 'George' OR Nome = 'Paula') AND Sobrenome = 'Pereira'
Tabela (14):
Matricula Nome Sobrenome
789234 George Pereira

Operador lógico IN

O operador IN é usado junto com WHERE para selecionar um campo com valor dentro de um conjunto de valores discretos. A sintaxe é

SELECT campo1, ..., campon
   FROM Tabela
   WHERE campo1 IN (valor1, ..., valorr)
SELECT * FROM Alunos WHERE Matricula IN (654987, 765098)
Tabela (15):
Matricula Nome Sobrenome
654987 Paula Torres
765098 Marcos Melo

SELECT INTO

A instrução SELECT INTO é usada para selecionar registros e campos de uma tabela e copiar o resultado retornado em uma nova tabela.

SELECT Coluna1, ..., Colunan INTO Tabela2 FROM Tabela1	WHERE <condições>

A Tabela2 será criada com os mesmos campos e relacionamentos da tabela inicial. Alguns casos são listados a seguir:

-- Faça uma cópia backup de Alunos
SELECT * INTO AlunosBackup FROM ALunos;

-- Faça uma cópia backup de Alunos cujo nome começa com 'Pa'
SELECT * INTO AlunosBackup FROM ALunos WHERE Nome LIKE 'PA%';

-- Faça uma cópia backup de Alunos em outro banco de dados (BDCopia)
SELECT * INTO AlunosBackup IN 'BDCopia' FROM ALunos;

-- Cria tabela vazia novoAlunos com estrutura idêntica a de Alunos
SELECT * INTO novoAlunos FROM Alunos WHERE 1 = 0;

INSERT INTO

A instrução INSERT INTO é usada para inserir novos registros em uma tabela. Ele pode ser usado em dois formatos:

INSERT INTO Tabela1 VALUES (valor1, ..., valorn)
-- ou
INSERT INTO Tabela1 (campo1, ..., campon)  VALUES (valor1, ..., valorn)

No primeiro caso \(n\), o número de valores inseridos deve ser igual ao número de campos da tabela e devem estar na ordem default. No segundo caso a ordem pode ser alterada mas campon) deve corresponder à valorn. Em ambos os casos o tipo de dado do campo deve ser respeitado. Por exemplo: as seguintes instruções aplicadas sobre a tabela Alunos:

-- Inserindo todos os campos
INSERT INTO Alunos VALUES (854254, 'João', 'Alves', 'jalves@yahoo.com', '15-03-2004', '31 885466112')
-- Inserindo alguns campos
INSERT INTO Alunos (Matricula, Nome, Sobrenome) VALUES (785294, 'Marta', 'Soares')

alteraria a tabela para

Tabela (16):
Matricula Nome Sobrenome email Nascimento Fone
734236 João Santos joao@yahoo.com 02-04-1998 61 123455667
789234 George Pereira george@gmail.com 04-04-2000 41 345678987
654987 Paula Torres ptorres@globo.com 25-01-2004 31 987854543
765098 Marcos Melo mamelo@gmail.com 25-01-2004 31 987843231
854254 João Alves jalves@yahoo.com 15-03-2004 31 885466112
785294 Marta Soares

Os valores de campos não fornecidos na última instrução ficam nulos (null, inexistência de valor) ou assumem um valor default definido na construção da estrutura da tabela.

UPDATE

A instrução UPDATE é usada para alterar registros já inseridos em uma tabela. Ela tem a sintax geral:

UPDATE Tabela1
   SET campo1 = valor1, ..., campon = valorn
   WHERE <condições>

O formato acima mostra que podemos quebrar as linhas de uma instrução SQL para torná-la mais legível. A cláusula WHERE <condições> limita quais os registros serão alterados. Sem ela todos os registros (todas as linhas da tabela) seriam alterados.

Por exemplo, podemos completar o registro relativo à aluna Marta em nossa tabela:

UPDATE Alunos
   SET Sobrenome = 'Alves', email = 'marta123@yahoo.com', Nascimento = '14-03-2001', fone = '21 956855441'
   WHERE Matricula = 785294
-- Para ver o resultado (os demais registros ficam inalterados)
SELECT * FROM Alunos WHERE Matricula = 785294

O resultado seria a tabela:

Tabela (17):
Matricula Nome Sobrenome email Nascimento Fone
785294 Marta Alves marta123@yahoo.com 14-03-2001 21 956855441

Novamente, se não tivéssemos especificado a condição Matricula = 785294 todos os registros, de todos os alunos seriam alterados.

Suponha que, por algum motivo, a escola tenha decido alterar o padrão de numeração das matrículas acrescentando o dígito 1 à esquerda de todas as matrículas. Isso seria o mesmo que somar 1000000 à todas as matrículas. Podemos conseguir isso com a seguinte operação:

UPDATE Alunos SET Matricula = Matricula + 1000000
-- Para ver o resultado (os demais campos ficam inalterados)
SELECT Matricula FROM Alunos
Tabela (18):
Matricula
1734236
1789234
1654987
1765098
1854254
1785294

DELETE

A instrução DELETE permite o apagamento de registros em uma tabela. Ela tem a sintax geral:

DELETE FROM Tabela1 WHERE <condições>

O formato acima mostra que podemos quebrar as linhas de uma instrução SQL para torná-la mais legível. A cláusula WHERE <condição> limita quais os registros serão apagados. Sem ela todos os registros (todas as linhas da tabela) seriam apagadas.

Por exemplo, podemos apagar os registros relativos aos alunos com sobrenome “Alves” de nossa nossa tabela:

DELETE FROM Alunos WHERE Sobrenome = 'Alves'

Dois alunos seriam removidos da tabela que ficaria assim:

Tabela (19):
Matricula Nome Sobrenome email Nascimento Fone
1734236 João Santos joao@yahoo.com 02-04-1998 61 123455667
1789234 George Pereira george@gmail.com 04-04-2000 41 345678987
1654987 Paula Torres ptorres@globo.com 25-01-2004 31 987854543
1765098 Marcos Melo mamelo@gmail.com 25-01-2004 31 987843231

Se não tivéssemos especificado uma condição para o apagamento todos os registros seriam apagados. A linha abaixo apagaria todos os registros da tabela Alunos:

DELETE FROM Alunos

A tabela e sua estrutura continuaria existindo.

Aliases

Aliases (nomes alternativos) são usados para simplificar uma consulta. Nossa tabela de exemplo é uma tabela pequena e simples. Na prática os bancos de dados e tabelas podem conter muitos campos. A possibilidade de renomear tabelas e campos pode ser muito útil, principalmente quando a consulta envolve mais de uma tabela e a consulta se refere às tabelas e campos mais de uma vez.

Por exemplo considerando que nossa tabela está no estado da Tabela (19) a consulta

SELECT Matricula, Nome + ', ' + Sobrenome AS NomeCompleto FROM Alunos

resulta em

Tabela (20):
Matricula NomeCompleto
1734236 João Santos
1789234 George Pereira
1654987 Paula Torres
1765098 Marcos Melo

Aqui foi feita uma concatenação das strings Nome + Sobrenome e o resultado renomeado como NomeCompleto.

Quando usamos várias tabelas de um banco de dados pode ocorrer que mais de uma delas tenha um campo com o mesmo nome. Nesse caso é obrigatória descriminar a que tabela nos referimos. A mesma consulta acima pode ser colocada na seguinte forma, com o mesmo resultado:

SELECT a.Matricula, a.Nome + ', ' + a.Sobrenome AS NomeCompleto FROM Alunos a

Aqui a tabela Alunos ganhou o alias a. a.Matricula se refere ao campo Matricula da tabela Alunos.

Agrupamentos e funções de grupos

Vamos acrescentar novas tabelas para considerar os agrupamentos. Suponha que a escola possui 4 funcionários identificados por um id único (um número de indentificação). Uma tabela armazena a relação entre id e nome (nome do funcionário). Outras tabela contém o número de horas trabalhadas por dia, para cada funcionário.

Tabela (21): Horas_trabalhadas
id dia horas
36 ’01-03-2019′ 6
41 ’01-03-2019′ 8
48 ’01-03-2019′ 2
58 ’01-03-2019′ 8
36 ’02-03-2019′ 5
41 ’02-03-2019′ 8
48 ’02-03-2019′ 1
58 ’02-03-2019′ 4
Tabela (22): Funcionarios
id Nome
36 Mariana Goulart
41 Tânia Ferreira
48 Humberto Torres
58 Francisco Pedroso

Diversas operações são permitidas sobre as linhas de uma tabela. Em particular

Instrução Efeito
GROUP BY Agrupa registros por valores do campo
Função Efeito
COUNT Conta o número de ocorrências do campo
MAX Fornece o valor máximo do campo
MIN Fornece o valor mínimo do campo
AVG Fornece a média dos valores do campo
SUM Fornece a soma dos valores do campo

Por exemplo, para calcular o número de horas trabalhadas por todos os funcionários podemos usar a consulta

SELECT SUM(horas) as soma FROM Horas_trabalhadas

que resulta em um único registro para um único campo:

Tabela (23):
soma
42

Para calcular o número de horas trabalhadas por cada funcionário fazemos a soma das horas com os campos de horas agrupados por cada funcionário.

SELECT id, SUM(horas) as soma
   FROM Horas_trabalhadas
   GROUP BY id
Tabela (24): Horas_trabalhadas
id horas
36 11
41 16
48 3
58 12

A consulta a seguir mostra o cálculo da média de horas trabalhadas por funcionário e de quantos dias cada um trabalhou.

SELECT id, AVG(horas) as media, COUNT(id) as numDias
   FROM Horas_trabalhadas
   GROUP BY id
Tabela (25): Média e número de dias trabalhados
id media numDias
36 5.5 2
41 8 2
48 1.5 2
58 6 2

Cláusula HAVING

A cláusula HAVING é usada para se estabelecer critérios sobre valores obtidos em funções agregadas. No SQL não é permitido usar WHERE para restringir resultados de uma consulta agregada. A consulta seguinte resultaria em erro:

SELECT id, SUM (horas)
   FROM Horas_trabalhadas
   WHERE SUM (horas) > 11   -- Isso geraria um erro
   GROUP BY id

Para esse efeito usamos HAVING, uma forma de se especificar condições sobre o resultado de uma função agregada.

SELECT id, SUM (horas) as soma
   FROM Horas_trabalhadas
   GROUP BY id
   HAVING soma > 11

Essa consulta gera a seguinte tabela, que é uma modificação da Tabela (24), satisfeita a condição soma > 11:

 

Tabela (24): Horas_trabalhadas
id soma
41 16
58 12

Instrução JOIN

É claro que a última tabela ficaria mais fácil de interpretar se, ao invés de conter apenas ids, ela contivesse também os nomes dos funcionários. Essa informação está contida na Tabela (22): Funcionarios. A instrução JOIN serve para ler dados relacionados, gravados em mais de uma tabela. Sua forma geral é:

SELECT tabela1.campo11, tabela1.campo12, tabela2.campo21, tabela2.campo22, ...
   FROM tabela1 INNER JOIN tabela2 ON tabela1.id1 = tabela2.id2

Esse comando seleciona todos os campo11 e campo12 da tabela1, campo21, campo22, … da tabela2, relacionados pela condição tabela1.id1 = tabela2.id2. OS campos id1 e id2 podem ter ou não os mesmos nomes. Usando aliáses essa consulta pode ser deixada mais clara (e isso se torna mais importante para consultas mais longas envolvendos muitos campos e tabelas):

SELECT t1.campo11, t1.campo12, t2.campo21, t2.campo22, ...
   FROM tabela1 t1 INNER JOIN tabela2 t2 ON t1.id1 = t2.id2

Por exemplo, se quisermos uma tabela com os mesmos resultados da tabela (24) mas incluindo nomes dos funcionários fazemos

SELECT ht.id, f.Nome, SUM(horas) as soma
   FROM Horas_trabalhadas ht
   INNER JOIN Funcionarios f ON ht.id = f.id
   GROUP BY ht.id HAVING soma > 11

Com o resultado:

Tabela (25): Horas trabalhadas por funcionário
id Nome soma
41 Tânia Ferreira 16
58 Francisco Pedroso 12

Existem outros tipos de junções ou JOINs no SQL:

  • (INNER) JOIN: Retorna registros com valores correspondentes nas duas tabelas.
  • LEFT (OUTER) JOIN: Retorna registros da tabela esquerda (a primeira na query) e os correspondentes na tabela direita.
  • RIGHT (OUTER) JOIN: Retorna registros da tabela direita e os registros correspondentes da tabela esquerda.
  • FULL (OUTER) JOIN: Retorna registros quando houver correspondência em qualquer uma das tabelas.
Variantes do operador JOIN

Sugestões de Leitura

  • Faroult, Stéphane; Robson, Peter: The Art of SQL, O’Reilly Media, Sebastopol, CA, 2006.
  • Taylor,Allen: SQL For Dummies, 9th Edition John Wiley & Sons, New Jersey, 2019.

O Futuro da Inteligência Artificial

Expectativa e Desafio Futuro

No campo das expectativas para um futuro muito próximo podemos mencionar as interfaces entre cérebro e computador mediadas por IAs, conectados à máquinas externas tais como exoesqueletos. Esses sistemas estarão disponíveis para pacientes com acidentes cérebro-vasculares, com traumas, doenças neurológicas, ou simplesmente como uma extensão de habilidades de uma pessoa saudável.

Nenhuma nova tecnologia é introduzida sem apresentar simultaneamente problemas e desafios em seu uso. Estima-se que um número relevante de empregos será perdido para a automação inteligente. Diferente das máquinas mecânicas, que substituíram o trabalhador braçal, agora é razoável considerar que computadores farão o trabalho de profissionais com níveis mais elevados de qualificação. Investimento em equipamentos, e não em pessoas, provavelmente aumentará o problema do desemprego e da concentração de renda.

O uso das máquinas para recomendações de conteúdo, por exemplo, tem se mostrado problemático em algumas plataformas. Buscando atrair a atenção do usuário e mantê-lo por mais tempo conectado e fidelizado as redes apresentam como sugestões conteúdos cada vez mais contundentes, muitas vezes envolvendo violência e intolerância. A indicação de conteúdo de fácil aceitação, em geral aprovado por muitos usuários, tende a esconder aqueles de menor circulação ou de gosto mais elaborado. Como resultado se observa a tendência de uniformização e formação de guetos, com a consequente inclinação à radicalização e intolerância. Junta-se a isso a facilidade para a geração inteligente de imagens, áudios e vídeos falsos que torna as campanhas de desinformação ainda mais nocivas e de difícil deteção.

Os problemas envolvendo a indústria da propaganda nos meios virtuais ficam exacerbados pelas práticas ilegais e imorais do roubo de dados. Dados se tornaram um produto valioso e a ausência de uma legislação atualizada estimula a prática da invasão de computadores e telefones pessoais e corporativos. Redes sociais importantes já foram flagradas vendendo informações sobre seus usuários que são usadas para o mero estímulo ao consumo ou para o atingimento de metas políticas muitas vezes obscuras e antidemocráticas.

A habilidade das IAs de reconhecer texto escrito e falado e extrair conteúdo das linguagens naturais agrava a ameaça à privacidade. Uma espionagem feita pelo microfone de um celular pode não apenas indicar que tipo de propaganda deve ser oferecida ao usuário mas também revelar traços que essa pessoa gostaria de manter privados, tais como traços de comportamentos íntimos ou a presença de uma doença.

Questões éticas, usualmente difíceis, ficam mais complexas na presença de IAs. Quem deve ser responsabilizado se um médico autômato comete um erro em seu diagnóstico ou procedimento? Quanta autonomia se pode atribuir à um juiz máquina ou a um automóvel auto-guiado? É aceitável permitir que um drone armado dispare contra um grupo que ele considera perigoso?

Provavelmente a afirmação do falecido físico Stephen Hawkings de que “O desenvolvimento de uma inteligência artificial completa pode determinar o fim da raça humana” seja pessimista em excesso.

É inegável, no entanto, que vigilância e responsabilidade devem ser elementos comuns no uso de toda nova tecnologia.

Referências

CHOLLET, F.. Deep Learning with Python. Nova Iorque: Manning Publications Co., 2018.

GOODFELLOW, I.; BENGIO, Y.; COURVILLE, A. Deep Learning: Cambridge, MA : MIT Press, 2017.

UNESCO. Artificial Intelligence in Education: Challenges and Opportunities for Sustainable Development, United Nations Educational, Scientific and Cultural Organization, Paris, 2019.

Inteligência Artificial

Onde o Aprendizado de Máquina é usado?

Máquinas treinadas podem ser empacotadas em aplicativos para computadores, telefones celulares ou circuitos com processadores que podem ser inseridos em outros equipamentos maiores, como automóveis e aviões, ou simplesmente serem carregados com o usuário.

Bons exemplos são os programas de busca e remoção de vírus de computadores e programas espiões que visam o roubo de dados pessoais ou corporativos. Novos vírus são disseminados a todo momento mas a maior parte de seu código replica o de vírus já detectados e combatidos. Sistemas inteligentes podem prever com boa exatidão quando um código representa um ataque ou, caso contrário, informar sobre possíveis riscos que ele representa. Da mesma forma um servidor de correio eletrônico (email) pode processar as mensagem recebidas e seus anexos em busca de spams, vírus, mensagens enviadas por remetentes cadastrados como perigosos ou prever outras anomalias.


Procedimentos de segurança de pessoas ou grupos podem ser automatizados. Filas de aeroportos ou de ingresso a um evento público de grande comparecimento podem ser varridas por meio de câmeras que localizam faces cadastradas em listas de criminosos ou encontrar outras características suspeitas que seriam de difícil identificação por funcionários humanos.

A análise de séries temporais, dados coletados ao longo do tempo, submetidas ao treinamento de máquina pode, em muitos casos, permitir a previsão de eventos futuros ou a inferência retrógrada de períodos passados que não foram documentados. Dois casos de interesse evidente são as previsões meteorológicas e da flutuação de mercados e bolsas de valores. Em ambos os casos as previsões automatizadas estão sendo rapidamente aprimoradas e os resultados cada vez mais úteis. A previsão meteorológica, por exemplo, permite o planejamento de ações de defesa ou de emergência em casos de tempestades. Empresas voltadas para as aplicações financeiras têm conseguido sucesso relevante nessa previsão, o que se reflete em lucro. Bancos e outros agentes financeiros usam a IA para previsão de comportamento de clientes, para sugestões de investimentos e prevenção de fraudes.

Um exemplo não óbvio da análise de séries temporais está nos aplicativos de reconhecimento de voz. Conversão direta de voz em texto ou vice-versa, de tradução ou de uso nos chamados assistentes pessoais, tais como o Alexa do Google e Siri da Apple são aplicações deste tecnologia. Através desses assistentes o usuário pode acionar outros aplicativos em seu aparelho pessoal, escolher músicas, enviar emails, entre outras funcionalidades.

A análise automática de textos já é usada nos tribunais brasileiros para triagem e encaminhamento de processos. Muitas questões estão em aberto no que se refere ao uso desses sistemas e se torna necessário discutir a inserção do assunto nos currículos de ensino de Direito.

O reconhecimento de significado de texto representa uma parte importante dos aplicativos de IA. Chatbots são aplicativos que simulam uma conversação com o usuário, fazendo pesquisas de opinião e preferência, sugerindo um procedimento para o usuário ou escolhendo o atendente humano que melhor responderá a suas demandas. A análise automática de um texto pode discriminar o estado de humor de quem o escreveu e sugerir a ele uma página na web de seu interesse ou um produto que ele esteja inclinado a consumir.

Muitas desta aplicações podem, e de fato o fazem, se beneficiar de um acesso direto à informação obtida por meio de sensores de natureza diversa, principalmente quando estão conectados à internet e transmitem dados em tempos real. Exemplos disso são as leituras de GPS (Global Positioning System ou Sistema Global de Posicionamento) que permitem a exibição de mapas de trânsito atualizados a cada instante, exibindo rotas de menor tráfego ou pontos de congestionamentos. Usando estes sistemas associados a diversos outros sensores, todos analisados por IA, automóveis autônomos podem circular pelas ruas das cidades provocando um número de acidentes inferior àqueles provocados por motoristas humanos. Da mesma forma um drone pode entregar produtos adquiridos remotamente diretamente nas mãos do consumidor.

Baseados na interação que fazemos com as páginas das chamadas rede sociais é possível a captura muito precisa de personalidades, gostos e tendências de um usuário, o que é usado pelos agentes de mídia para veicular propaganda de consumo, de comportamento ou política. Os provedores de conteúdo áudio-visuais, tais como o Netflix, o Youtube e Spotify, usam IAs para acompanhamento dos hábitos de seus usuários para indicar novos acessos à filmes, músicas ou outros produtos de qualquer natureza.

As aplicações de máquinas inteligentes são particularmente animadoras no campo da saúde, em especial para diagnósticos por imagem. Doenças de pele ou dos olhos, ou células cancerosas podem ser detectadas por meio da análise de imagens, muitas vezes com precisão superior à obtida por um técnico humano. O estudo do registro médico pormenorizado de um paciente pode indicar tendências e sugerir formas viáveis de tratamento.

Usuários dos jogos de computadores também são expostos à decisões de máquinas rotineiramente. A industria dos jogos foi uma das primeiras a se aproveitar desta tecnologia e muitos jogos lançam mão de IA para tomadas de decisões e para a animação de personagens virtuais que povoam os mundos de fantasia dos jogos.

Telescópio Espacial kepler – representação artística

A inteligência artificial, com sua habilidade de análise de grande volume de dados, é um recurso poderoso na pesquisa científica. Um exemplo brilhante dessa faceta foi a descoberta anunciada pela NASA em março de 2019 de dois exoplanetas por meio de um algoritmo chamado AstroNet-K2, uma rede neural modificada para o estudo dos dados colhidos pelo telescópio espacial Kepler.

IA e Educação

A Educação é um setor tradicionalmente refratário às novas tecnologias e as novidades demoram para entrar na sala de aula. Apesar disso muitas propostas envolvendo IA têm surgido, algumas delas já em aplicação.

O professor hoje compete na atenção dos alunos com uma variedade de estímulos eletrônicos, jogos, páginas da web interativas e ambientes de interação social. Qualquer sistema educacional no presente e futuro próximo deve oferecer estímulo similar ao encontrado nesses meios, buscando dialogar com os alunos no ambiente de interatividade digital com que estão bem familiarizados.

Ainda que os computadores já sejam, há algum tempo, utilizados no manejo da burocracia escolar, sistemas inteligentes podem agilizar esse processo. Professores gastam boa parte de seu tempo em atividades burocráticas, não relacionadas com o ensino em si. A avaliação de exames e o preenchimento de formulários, o acompanhamento de frequências às aulas, o contato permanente com pais e responsáveis e o controle de estoque de material escolar, todas são tarefas que podem ser facilitadas com o uso de IA. O mesmo ocorre com o gerenciamento de matrículas, formulação de calendários e manejo de pessoal. Para o aluno um assistente escolar pode agendar compromissos virtuais ou não, acompanhar a rotina de estudos e contato com professores.

É no campo puramente acadêmico, no entanto, que se pode esperar os melhores resultados. Sistemas inteligentes tem sido treinados para a personalização com ajuste super fino de ementas e fluxos de estudo para o indivíduo, levando em conta suas habilidades e deficiências. Com a adoção de textos eletrônicos a informação antes contida em grandes volumes de papel pode ser, de modo simples e de baixo custo, fragmentada em guias menores de estudos, contendo blocos lógicos completos com referência a recursos multimídia e conteúdo expandido. Sistemas de IA podem fornecer uma interface interativa capaz de responder perguntas ou indicar referências visando esclarecer pontos pouco compreendidos. Uma IA pode auxiliar o professor inclusive por meio de diálogos falados, resolvendo dúvidas e ajudando na solução de exercícios, enquanto a análise de imagens capturadas por câmeras pode indicar o nível de concentração ou dispersão dos estudantes.

Associada ao uso da apresentação dinâmica de conteúdo um sistema treinado por IA e subsidiado por avaliações permanentes e automáticas de desempenho pode indicar o melhor roteiro, as necessárias revisões e ritmo do aprendizado. Tutores automáticos podem acompanhar e sugerir o ritmo de estudo de um estudante. A avaliação permanente, além de tornar desnecessária a temida temporada de provas, avaliará o nível atual de conhecimento do aluno, insistindo em exemplos e exercícios caso um conceito não esteja bem assimilado através da apresentação de questões com níveis crescentes de dificuldade, sugerindo o retorno para níveis mais básicos ou a progressão para tópicos mais avançados. Ele pode identificar lacunas no entendimento e apresentar as intervenções corretas para preencher essas deficiências.

Simultaneamente com a avaliação de testes e exercícios podem ser inseridos mecanismos para a detecção de dificuldades outras que não as puramente acadêmicas, tais como deficiências de visão e concentração para alunos mais jovens.

Evidentemente nenhum sistema, por mais arrojado que seja, poderá se furtar ao estímulo de aspectos humanos básicos tais como a criatividade, cooperação entre indivíduos e desenvolvimento ético. Principalmente nas primeiras fases de implantação dos sistemas inteligentes nas escolas, visto que o efeito completo da exposição a sistemas artificiais não é plenamente conhecido, não se pode permitir uma dependência excessiva nas máquinas. Alunos devem receber estímulo para realizar pesquisas tradicionais em bibliotecas e usar livros físicos. A interação entre alunos e educadores e colegas deve ser uma prioridade. Além disso, em um contexto onde a informação, como acesso aos dados, e a capacidade de processamento destes dados estão super facilitados pela presença de computadores, a criatividade e a habilidade para a solução de problemas, individualmente ou em grupo, deve ser o foco do processo educativo.

Grande parte do desafio das instituições de ensino em face da explosão da IA consiste em treinar profissionais para o uso e desenvolvimento dos próprios sistemas inteligentes. Um usuário não especialista em computação deve adquirir compreensão básica do mecanismo de funcionamento das máquinas, com conhecimento mínimo da arquitetura destes sistemas e da análise estatística utilizada por eles. Caso contrário não saberá discernir que tipo de demandas são adequadas para as IAs nem terá competência para interpretar os resultados destes processos.

O treinamento de especialistas com competência para desenvolver sistemas inteligentes não é desafio menor. A inteligência de máquina e os sistemas de aprendizado dependem profundamente de matemática avançada, em particular a álgebra linear e a estatística, e de programação e lógica. Existe risco evidente do uso das ferramentas mais modernas como caixas pretas onde um programador pode colocar em funcionamento sistemas complexos sem ter um bom domínio da tecnologia envolvida. Além da dependência cultural e tecnológica dos centros desenvolvedores isso cria restrição severa sobre a habilidade para tratar de novos desafios, especialmente aqueles de interesse restrito à comunidade local, tais como problemas dos países em desenvolvimento que não foram devidamente tratados pelos grandes centros de pesquisa.


Expectativa e Desafio Futuro

Inteligência Artificial e Aprendizado de Máquina


O que são e para que servem?

O aperfeiçoamento de tecnologias da informação, não diferente de outras tecnologias, tem causado grande impacto na sociedade humana. Grande parte deste impacto é positiva no sentido de aprimorar a experiência do indivíduo, liberando-o de tarefas mecânicas pesadas ou atividades intelectuais extenuantes. No geral a tecnologia amplia a capacidade humana de transformação da natureza ao mesmo tempo em que facilita a exploração científica que, por sua vez, realimenta o avanço tecnológico. No entanto os mesmos aspectos que podem ser benéficos também podem introduzir desafios. Máquinas, como ferramentas mecânicas, aumentam a eficiência e produtividade de um indivíduo, colateralmente provocando desemprego e concentração de renda. Da mesma forma máquinas eletrônicas que simulam as atividades de cognição e interpretação humanas estão, já há alguns anos, transformando a sociedade e as relações entre indivíduos de modo construtivo, em certa medida. Muitos aspectos desta transformação são claramente nocivos, como a evidente tendência da substituição de trabalhadores por máquinas “inteligentes” ou, por exemplo, a manipulação de opiniões para fins políticos usando o levantamento de perfis psicológicos. No entanto esta é uma tecnologia nova e de crescimento muito rápido e a maior parte do impacto causado por ela continua desconhecido e deve ser considerado com atenção.

A inteligência artificial (IA) começou a ser desenvolvida na década de 1950, em um esforço para automatizar atividades antes empreendidas apenas por humanos. Tomadas de decisão básicas podem ser implementadas por equipamentos simples, tal como um termostato que limita a atividade de um condicionador de ar desligando-o quando uma temperatura mínima é atingida. Processadores, que são o núcleo dos computadores eletrônicos, são formados por grande número de circuitos capazes de implementar testes lógicos básicos descritos na chamada Álgebra de Boole. Com o desenvolvimento da programação, que consiste em uma fila de instruções a serem seguidas pelo computador, tornou-se viável a elaboração de sistemas especialistas. Esses sistemas são compostos por uma longa série de instruções, geralmente com acesso a um repositório de informações (um banco de dados) para a tomada de decisões. Eles podem classificar vinhos, jogar xadrez, resolver problemas matemáticos usando apenas símbolos, entre muitas outras tarefas.

Apesar do sucesso de tais sistemas especialistas existem tarefas de complexidade muito superior à de jogar xadrez ou classificar objetos de um conjunto, mesmo que com milhares de elementos. Uma tarefa como a identificação e localização de objetos em uma imagem, por exemplo, exigiria um conjunto gigantesco de linhas de instruções ou informações em bancos de dados. Para tratar grandes volumes de dados e questões que não admitem soluções por meio de algoritmos fixos, mesmo que complexos, foi desenvolvido o Aprendizado de Máquina Artificial (Machine learning).

 

Ada Lovelace e Charles Babbage

Nas décadas de 1830 e 1840, quando Ada Lovelace e Charles Babbage desenvolveram o Analytical Engine, o primeiro computador mecânico, eles não o consideravam uma máquina a ser utilizada para a solução de problemas genéricos. Pelo contrário, ele foi concebido e utilizado em problemas específicos na área da análise matemática. Nas palavras de Lovelace:

O Analytical Engine não tem pretensões de criar coisa alguma. Ele apenas pode fazer aquilo que conhecemos e sabemos como instruí-lo em sua execução… Sua função é a de nos ajudar com o que já estamos familiarizados.…”

 

Essas conclusões foram analisadas por Alan Turing, o pioneiro da IA, em seu artigo de 1950 “Computing Machinery and Intelligence”, onde são introduzidos os conceitos de teste de Turing e outros que se tornaram fundamentos da IA. Ele concluiu que máquinas eletrônicas poderiam ser capazes de aprendizado e originalidade. Aprendizado de máquina (machine learning) é a resposta positiva para a pergunta: um computador pode ir além das instruções com as quais foi programado e aprender a executar tarefas?

O aprendizado de máquina representa um novo paradigma na programação. Ao invés de armazenar na memória do computador um conjunto de regras fixas a serem usadas na execução de uma tarefa o computador é carregado com algoritmos flexíveis que podem ser modificados por meio de treinamento. O aprendizado consiste em exibir para a máquina um conjunto grande de exemplos anotados (devidamente etiquetados) por um humano ou por outra máquina previamente treinada. Uma vez treinado o mesmo sistema será capaz de identificar corretamente (ou com bom nível de precisão) casos novos além daqueles antes exibidos.

 

Programação clássica x Aprendizado de Máquina

 

Suponha, por exemplo, que queremos identificar em uma pilha de fotos aquelas que contêm imagens de gatos ou cachorros. O código contendo os algoritmos é alimentado com fotos dos animais, cada uma devidamente etiquetada. Uma forma de avaliação de erro da previsão é fornecida juntamente com um algoritmo flexível que pode ser alterado automaticamente de forma a minimizar os erros da avaliação. Por meio da leitura repetida destas imagens o algoritmo é modificado para produzir o menor erro possível de leitura.

 

Treinamento de máquina

 

A este processo chamamos de treinamento. Em terminologia técnica dizemos que ele consiste em alterar os parâmetros do algoritmo de forma a minimizar os erros. Uma vez encontrados estes parâmetros o algoritmo pode ser usado para identificar novas fotos contendo gatos ou cachorros. Ao treinamento feito com o uso de dados etiquetados é denominado supervised learning (aprendizado supervisionado). É também possível submeter à análise do computador um conjunto de dados não identificados com a demanda de que o o algoritmo identifique padrões de forma autônoma e classifique elementos de um conjunto por similaridade desses padrões. No unsupervised learning (aprendizado não supervisionado) é possível que o sistema inteligente distinga padrões que mesmo um humano não seria capaz de perceber.

Machine learning é um método de análise e processamento de dados que automatiza a construção do algoritmo de análise.

O treinamento de máquinas depende da velocidade e capacidade de computadores mas, também, do acesso à informação ou dados. Esse acesso é fornecido pela atual conectividade entre fontes diversas de dados, armazenados de forma estruturada ou não. A habilidade dos computadores de realizar uma análise sobre um volume muito grande desses dados leva ao conceito de Big Data. A operação de busca e coleta desses dados é a atividade de Data Mining (mineração de dados) enquanto a seleção e interpretação desses dados é eficientemente realizada por sistemas inteligentes.

xkcd.com

Embora os primeiros passos na construção de sistemas de aprendizado tenham sido inspirados no funcionamento de cérebros e neurônios humanos (ou animais), as chamadas redes neurais artificiais não são projetadas como modelos realistas da arquitetura ou funcionalidade biológica. A expressão deep learning ou aprendizado profundo se refere apenas às múltiplas camadas usadas para o aprendizado artificial. A plasticidade do cérebro biológico, que é a capacidade de partes do cérebro de se reordenar para cumprir tarefas diferentes daquelas em que estava inicialmente treinado, levantou a hipótese de que algoritmos simples e comuns podem ser especializados para resolver tarefas diversas. Reconhecimento de imagens ou textos, por exemplo, podem ser efetuados por estruturas similares. A neurociência mostrou que a interação de partes simples pode exibir comportamento inteligente e complexo. Considerando as grandes lacunas existentes no entendimento da inteligência biológica, a memória e outras funções dos organismos vivos, é de se esperar que os avanços nessa área da ciência, juntamente com a evolução dos computadores, ainda venha a oferecer guias importantes para o aperfeiçoamento da inteligência artificial.


Onde o Aprendizado de Máquina é usado?

Linguagem de Scripts para Linux


Introdução ao BASH

Para interagir com o seu sistema operacional (no nosso caso o Linux) você pode usar interfaces gráficas ou GUI (graphic user interfaceem>, as famosas janelas) ou rodar um programa que permite que os comandos sejam inseridos um a um através de linhas de comando (command line interfaces, CLIs). Existem vários destes programas (ou Shells) mas trataremos aqui de bash (Bourne Again SHell, uma versão muito usada e já instalada na maioria das distribuições linux.

Muitas vezes, quando você usa um computador, uma tarefa pode ser realizada mais facilmente através de um comando de linha, escrito em um terminal. Por exemplo, suponha que queremos obter em um texto toda a lista de músicas que se encontram no diretório (ou pasta). Uma forma de fazer isto seria a seguinte:

Abra o terminal e digite

$ cd ~/Musica
$ ls > minhas_musicas.txt

(1) Listas de comandos podem ser encontradas em Site: SS64 ou Linux commands.

Faça suas experiências com os comandos de linha com cuidado. Nunca execute um comando cuja ação você desconhece. Embora seja difícil que um uusário sem permissão de surperusuário ou admnistrador faça grandes estragos no sistema, você pode apagar dados ou corromper programas instalados dentro de sua conta. Não se esqueça: faça sempre cópias de segurança!

Nestes exemplos $ é o prompt de comandos, a indicação de que o computador está pronto para receber instruções. O comando cd troca o foco da execução para o diretório ~/Musica, onde ~ é um atalho para representar a pasta do usuário, (home/usr). A segunda linha faz uma listagem de todos os arquivos usando ls (list screen) e, ao invés de exibí-los na tela, (devido ao sinal > ou pipe, redirecionador) envia esta lista para um arquivo de nome minhas_musicas.txt. Poderíamos ainda filtrar a lista usando ls *.mp3, e apenas os arquivos com extensão mp3 seriam listados1.

Observe agora que a Shell permite comandos encadeados ou seja, a entrada de vários comandos de uma só vez. É possível inclusive passar resultados de um comando para outro em um único passo. Para fazer isto escrevemos os comandos na mesma linha e os separamos por um ponto e vírgula (;):

$ cd ~/Musica; ls > minhas_musicas.txt

Essa linha efetuará o mesmo que as duas linhas do exemplo anterior. Para ver o conteúdo no novo arquivo criado digite gedit minhas_musicas.txt ou clique no arquivo de dentro de um gerenciador de arquivos como o Nautilus ou Thunar. Também é possível listar o arquivo de caracteres usando o comando cat minhas_musicas.txt.

Com esta técnica você pode escrever linhas com até 255 caracteres. Se uma sequência de ações for usada com frequência pode ser útil gravá-la em um arquivo, que depois pode ser executado quando necessário. Para isto use um editor qualquer que possa gravar arquivos como uma sequência simples de caracteres ASCII (isto quer dizer: sem comandos de formatação). O Ubuntu (e várias outras distribuições) traz o gedit ou kate (na distribuição KDE). Você também pode usar o geany, bluefish ou outro qualquer de sua escolha.

Uma lista de comandos gravada em um arquivo executável é chamada de script. Para especificar que se trata de um shell script colocamos na primeira linha a seguinte informação:

#!/bin/bash

O sinal de sustenido (#) em uma linha qualquer (exceto na primeira linha) é usado para indicar um comentário, um trecho que não é executado pela shell. Na primeira linha ele possui um significado especial: #! indica que o arquivo a seguir deverá ser executado pela bash shell fornecendo o caminho onde bash está instalado (normalmente em /bin/bash). Outros comandos, a serem executados na ordem em que se encontram, podem ser inseridos em linhas sucessivas. Você ainda pode usar o ponto e vírgula para separar comandos na mesma linha mas, em um script isto não é necessário nem recomendado. É mais fácil ler e compreender scripts onde cada linha contém um único comando.

O seguinte exemplo ilustra o conceito:

#!/bin/bash
# Esta linha é um comentário e não é executada
# Primeiro faça uma lista de músicas (mp3 e wav)
cd ~/Musica
ls *.mp3 > MusicasMp3
ls *.wav > ArquivosWav
# Faça uma lista de livros no formato pdf, na pasta ~/Livros
cd ~/Livros
ls *.pdf > LivrosEmPdf

Evidentemente estas linhas supõem a existências das pastas ~/Musicas e ~/Livros caso contrário uma mensagem de erro será exibida. Comentários são úteis para tornar mais legíveis os scripts, principalmente para o caso de outro usuário (ou você mesmo, no futuro) utilizar o script. Grave seu script com o nome lista_arquivos em uma pasta /.scripts (ou outro nome de sua preferência). Para executar esse script podemos digitar:

# se você já está na pasta scripts:
$ ./lista_arquivos
# se você não está na pasta scripts:
$ ~/.scripts/lista_arquivos

Alternativamente, para que um script seja encontrado a partir de qualquer outro diretório é necessário informar à shell como encontrá-lo. A shell usa uma “variável de ambiente” ( environment variable) chamada PATH para localizar onde estão os arquivos a serem executados. Para compreender isto melhor abra um terminal e digite:

$ echo $PATH
/usr/local/bin:/usr/bin:/bin

A segunda linha é a resposta (ou output) do comando echo, destinado a exibir informações, indicando que neste computador a shell fará uma busca nos diretórios /usr/local/bin, /usr/bin e /bin quando um comando for emitido. Observe que nossa pasta de scripts não está incluída. Para que o arquivo lista_arquivos seja executado podemos acrescentar a pasta onde ele reside ao PATH:

PATH=$PATH:/.scripts
$ echo $PATH
/usr/local/bin:/usr/bin:/bin: /.scripts

(2) Lembrando:

. Atalho para o diretório atual
cd ~ Para diretório home.
cd .. Volta para o dir pai

Observe que PATH contém agora a pasta /.scriptscode>. Esta alteração, no entanto, permanece válida apenas durante a sessão do terminal, ou dentro do arquivo de script de onde ela foi emitida. Veremos depois como alterar de forma permanente esta variável.

O ponto2, na primeira linha não comentada, é uma referência ao diretório atual, neste caso /.scripts. O til na outra linha, como já vimos, é um atalho para a pasta do usuário, o mesmo que /home/nome_do_usuário.

O último passo consiste em tornar este arquivo um executável. Para isto use o comando chmod (change mode):

$ chmod u+x teste1
# agora você pode executar o arquivo teste1
$ ./teste1

Se você procurar nas pastas ~/Musicas e ~/Livros deverá encontrar os arquivos recentemente gravados com o conteúdo esperado! O sistema de permissões do Linux (diretamente copiado do Unix) constitui uma das grandes vantagens deste sistema operacional. Por causa dele um usuário só pode alterar arquivos de sua propriedade enquanto arquivos de sistema só podem ser alterados pelo superuser ou gerente do sistema. Mesmo em seu próprio computador você não faz (ou pelo menos, não deve fazer) login como superuser.

Para alterar o PATH de modo definitivo você pode usar os seguintes procedimentos: primeiro verifique seu caminho atual usando o comando: $ echo $PATH. Para alterar a variável PATH para todos os usuários do sistema edite o arquivo /etc/profile (como root) e modifique a linha que começa com "PATH =".

sudo gedit /etc/profile
# forneça seu password
# procure a definição de PATH e edite para: PATH = "$PATH: $HOME/.scripts

(3) O ponto (.) como primeiro caracter do nome do arquivo .bash_profile ou indica que este é um arquivo oculto, um arquivo que não aparece normalmente em listagens requisitadas com o comando ls nem dentro do gerenciador de arquivos. Para listar arquivos ocultos use ls -a ou pressione Ctrl-H de dentro do Nautilus ou do Thunar (ou outro gerenciador de arquivos). Diretórios também podem ser ocultos da mesma forma.

(4) Segundo o manual online de bash (man pages) o arquivo .bash_profile é executado quando o usuário faz login em uma shell. Se você já está logado e abre uma janela de terminal (por exemplo) o arquivo .bashrc é executado.

Para alterar o PATH de um único usuário edite o arquivo /home/nome_do_usuario/.bash_profile ou .bashrc(Veja nota4). A especificação para o caminho no /etc/.bash_profile, ou /etc/.bashrc, é análoga ao caso anterior. Agora você não precisa usar sudo pois o arquivo é de sua propriedade e você tem permissão para alterá-lo.

gedit /etc/.bash_profile
# forneça seu password
# procure a definição de PATH e edite para: PATH = "$PATH: $HOME/scripts
export PATH

A linha de comando PATH = "$PATH: $HOME/scripts pega o conteúdo da variável de ambiente PATH já definida para todos os usuários no arquivo /etc/profile, e acrescenta a ela o nome do diretório $HOME/scripts (ou qualquer outro que você queira incluir). O comando export na última linha serve para que a variável fique visível fora do script onde ela foi definida.

Recapitulando: Para escrever um arquivo executável você dever informar em seu cabeçalho quem o executará (#!/bin/bash no caso de bash, #!/bin/env python no caso de um script Python, etc.Depois você deverá informar o caminho completo para a sua execução ou colocar o diretório onde seu script está na variável path. Finalmente você deve torná-lo um executável com chmod.

Para saber um pouco mais sobre as permissões5 de um arquivo vamos executar o comando ls -l, onde -l é uma chave (opção) para exibir permissões:

$ ls -l teste1
 -rwxr-xr-- 1
 usuario_1 grupo_1 227 Jun 8 21:22
teste1

(5) Permissões:

r permissão para leitura(read)
w permissão para escrever (write)
x permissão para executar (execute)
- substitui r, w, x se a permissão é negada

As permissões são listadas por meio de 9 caracteres: o primeiro indica o tipo do arquivo (d, se é um diretório, l para links e para arquivos comuns. Em seguido temos 3 grupos formados por 3 letras r, w, x (veja tabela) que se referem ao dono do arquivo (o usuário que o criou), ao grupo a que este usuário pertence, e aos demais usuários do computador ou rede. No exemplo acima teste1 é um arquivo () pertencente à usuario_1, grupo_1. O dono pode ler, escrever (gravar) e executar (rwx), usuários do grupo podem ler e executar (r-x) mas não modificar este arquivo, e os demais usuários podem apenas ler (r–).

Exibindo valores e resultados

Para exibir o valor da variável PATH, uma variável do sistema estabelecida durante o boot, usamos o comando echo $PATH. Também podemos usar echo para exibir mensagens de textos:

$ echo Uma mensagem para seu usuario ...
 Uma mensagem para seu usuario ...
$ echo # pula uma linha
$ echo "Um texto pode ser delimitado por aspas duplas ou simples"
Um texto pode ser delimitado por aspas duplas ou simples
$ echo ou ate mesmo aparecer sem nenhuma aspas ou ate mesmo aparecer sem nenhuma aspas

Observe que não é obrigatório o uso de aspas embora, para alguns usuários, pode ser mais claro ler programas onde as strings estejam delimitadas. Mensagens são úteis em um script, por exemplo, para passar informações sobre o funcionamento ou requisitar a digitação de algum dado.

echo "Os seguintes usuarios estao logados no sistema:"
who

O comando who exibe todos os usuários logados no momento. Para exibir uma informação sem trocar de linha usamos o parâmetro -n.

echo -n "Hoje e: " 	date
# O script acima exibe algo como: 	Hoje e: Wed Jun 22 11:29:23 BRT 2011

Programação com R

Se você decidir ler esta seção mais tarde, pule para a seção Aquisição de Dados.

Esta seção apresenta uma formalização um pouco mais rigorosa dos conceitos do R como linguagem de programação. Em uma primeira leitura, para aqueles que ainda estão se familiarizando com a linguagem, ela pode ser pulada e lida mais tarde. Ela contém um pouco de repetição do material já visto, para fins de completeza.

Objetos

R é uma linguagem de programação de array, funcional e orientada a objeto. Todos os elementos de R, variáveis de dados e funções, são objetos. Não se pode acessar locais da memória diretamente e todos os objetos usados na execução de um programa são armazenados em memória RAM. Isso acaba tendo um peso importante quando se processa um grande volume de dados.

Linguagens de programação de arrays (também chamadas de linguagens vetoriais ou multidimensionais) são linguagens onde operações sobre objetos multidimensionais (vetores, matrizes, etc.) generalizam as operações sobre escalares de forma transparente. Elas permitem um código mais conciso e legível.

Todos os objetos possuem atributos que são meta-dados descrevendo suas características. Estes atributos podem ser listados com a função attributes() e definidos com a função attr(). Um desses atributos, bastante importante, é a classe de um objeto pois as funções de R usam essa informação para determinar como o objeto deve ser manipulado. A classe de um objeto pode ser lida ou alterada com a função class().

Existem os seguintes tipos de dados: Lógico ou booleano (logic), numérico (numeric), inteiro (integer), complexo (complex), caracter (character) e Raw.

Estes dados podem ser agrupados em estruturas de dados. Existem dois tipos fundamentais de estruturas: vetores atômicos e vetores genéricos. Vetores atômicos são matrizes de qualquer dimensão contendo um único tipo de dados. Vetores genéricos são também chamados de listas e são compostas por vetores atômicos. Listas são recursivas, no sentido de que podem conter outras listas.

Uma variável não precisa ser inicializada nem seu tipo declarado, sendo determinado implicitamente a partir do conteúdo do objeto. Seu tamanho é alterado dinamicamente.

Não existe o tipo “escalar” em R. Um escalar é simplesmente um vetor com um único elemento. Portanto a atribuição u <- 1 é apenas um atalho para u <- c(1).

Uma matriz é um vetor atômico acrescentado de um atributo dim com dois elementos (o número de linhas e de colunas). No exemplo seguinte, um vetor é transformado em uma matriz e depois recuperado como vetor:

> v <- 1:12
> print(v)
 [1]  1  2  3  4  5  6  7  8  9 10 11 12
> class(v)
[1] "integer"
> x <- c(1,2,3,4,5,6,7,8)
> class(x)
[1] "numeric"
> attr(v, "dim") <- c(2,6)
> print(v)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    3    5    7    9   11
[2,]    2    4    6    8   10   12
> class(v)
[1] "matrix"
> # Um atributo arbitrário pode ser incluído
> attr(v, "nome") <- "minha matriz"

> attributes(v)
$dim
[1] 2 6
$nome
[1] "minha matriz"

> attr(v, "nome") <- NULL   # o atributo é removido
> attributes(v)
$dim
[1] 2 6
> # Um atributo pode ser alterado
> dim(v) <- c(3,4)
> print(v)
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
> # Removido o atributo "dim" v volta a ser um vetor
> attr(v, "dim") <- NULL
> v
 [1]  1  2  3  4  5  6  7  8  9 10 11 12

A atribuição v <- 1:4 é idêntica à v <- c(1:4) e análoga, mas não idêntica à v <- c(1, 2, 3, 4). Nos dois primeiros casos o resultado é um vetor de inteiros. No terceiro temos um vetor numérico (de ponto flutuante).

Existem funções para a marcação de atributos: dim(), dimnames(), names(), row.names(), class() e tsp() (usado para a criação de séries temporais). Estas funções são preferíveis à simplesmente usar attr(vetor, "atributo") porque fazem um tratamento e análise dos parâmetros usados, emitindo notificações de erros mais detalhadas.

A igualdade entre objetos atômicos pode ser testada com o uso do operador ==, que verifica recursivamente a identidade de cada um dos elementos dos objetos comparados, ou da função identical(), que verifica a igualdade completa entre os dois objetos.

> a <- c(1,3,5); b <- c(1,3,5); c <- c(1,2,5)
> a==b
[1] TRUE TRUE TRUE
> a==c
[1]  TRUE FALSE  TRUE
> identical(a,b)
[1] TRUE
> identical(a,c)
[1] FALSE

Listas e Data Frames

As listas são coleções de vetores atômicos, não necessariamente de mesmo tipo. Elas são recursivas no sentido de que podem ter outras listas como seus elementos. Data frames são listas onde todos os vetores possuem o mesmo comprimento. Muitas funções recebem listas como argumentos ou retornam listas.

Para exemplificar vamos usar uma lista contendo as 5 primeiras observações do data frame warpbreaks, com 3 variáveis.

> quebras <- head(warpbreaks, n=5)
> quebras
  breaks wool tension
1     26    A       L
2     30    A       L
3     54    A       L
4     25    A       L
5     70    A       L

> # Usamos unclass() para ver seus componentes
> unclass(quebras)
$breaks
[1] 26 30 54 25 70

$wool
[1] A A A A A
Levels: A B

$tension
[1] L L L L L
Levels: L M H

attr(,"row.names")
[1] 1 2 3 4 5

> # Usamos attributes() para ver seus atributos
> attributes(quebras)
$names
[1] "breaks"  "wool"    "tension"

$row.names
[1] 1 2 3 4 5

$class
[1] "data.frame"

A igualdade entre objetos não atômicos não é implementado com o operador ==. Neste caso é necessário usar a função identical(), que verifica a igualdade completa entre os dois objetos.

> u <- list(v1=1,v2=2); v <- u
> v==u
Error in v == u : comparison of these types is not implemented
> identical(u,v)
[1] TRUE

> # identical testa a identidade entre quaisquer dois objetos:
> f <- function(x,y) x+y; g <- function(x,y) x+y
> identical(f,g)
[1] TRUE

A função unclass() retorna uma cópia de seu argumento sem seus atributos de classe. attributes() retorna uma lista com os atributos de seu argumento.

Selecionar partes de uma lista é uma operação importante em R. Para ilustrar algumas operações vamos usar o data frame iris que é uma lista contendo 5 vetores atômicos. Ela contém os campos (ou observações) Sepal.Length, Sepal.Width, Petal.Length, Petal.Width e Species. Relembrando, a função unclass(iris) exibe todos os valores em cada campo e seus atributos, separadamente. A função attributes(iris) exibe apenas os atributos. No exemplo abaixo aplicamos o agrupamento K-means usando a função kmeans(). Em seguida exploramos o objeto retornado que é uma lista.

> head(iris, n=2)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa

> # Para selecionar apenas os 4 primeiros campos usamos iris[1:4]

> kGrupo <- kmeans(iris[1:4],3)
> typeof(kGrupo)    # para ver de que tipo é o objeto
[1] "list"
> length(kGrupo)    # kGrupo é uma lista com 9 elementos
[1] 9
> print(kGrupo)     # para listar todos os elementos do objeto
K-means clustering with 3 clusters of sizes 50, 38, 62

Cluster means:
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1     5.006000    3.428000     1.462000    0.246000
2     6.850000    3.073684     5.742105    2.071053
3     5.901613    2.748387     4.393548    1.433871

Clustering vector:
  [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [31] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 2 3 3 3 3 3 3 3
 [61] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 3 3 3 3
 [91] 3 3 3 3 3 3 3 3 3 3 2 3 2 2 2 2 3 2 2 2 2 2 2 3 3 2 2 2 2 3
[121] 2 3 2 3 2 2 3 3 2 2 2 2 2 3 2 2 2 2 3 2 2 2 3 2 2 2 3 2 2 3

Within cluster sum of squares by cluster:
[1] 15.15100 23.87947 39.82097
 (between_SS / total_SS =  88.4 %)

Available components:

[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss" "betweenss"
[7] "size"         "iter"         "ifault"

> str(kGrupo)
List of 9
 $ cluster     : int [1:150] 1 1 1 1 1 1 1 1 1 1 ...
 $ centers     : num [1:3, 1:4] 5.01 6.85 5.9 3.43 3.07 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:3] "1" "2" "3"
  .. ..$ : chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
 $ totss       : num 681
 $ withinss    : num [1:3] 15.2 23.9 39.8
 $ tot.withinss: num 78.9
 $ betweenss   : num 603
 $ size        : int [1:3] 50 38 62
 $ iter        : int 2
 $ ifault      : int 0
 - attr(*, "class")= chr "kmeans"

> # A lista contém os seguintes atributos
> attributes(kGrupo)
$names
[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
[6] "betweenss"    "size"         "iter"         "ifault"

$class
[1] "kmeans"

> # sapply(objeto, class) exibe a classe de cada elemento na lista
> # A função sapply é tratada com maiores detalhes na próxima seção

> sapply(kGrupo, class)
     cluster      centers        totss     withinss tot.withinss    betweenss
   "integer"     "matrix"    "numeric"    "numeric"    "numeric"    "numeric"
        size         iter       ifault
   "integer"    "integer"    "integer"

> # Podemos visualizar simultaneamente o segundo elemento, "centers"
> # que fornece uma matriz com os valores do centro de cada agrupamento
> e size, 7º elemento, com o número de pontos em cada grupo

> kGrupo[c(2,7)]
$centers
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1     5.006000    3.428000     1.462000    0.246000
2     6.850000    3.073684     5.742105    2.071053
3     5.901613    2.748387     4.393548    1.433871

$size
[1] 50 38 62

> # Para visualizar o segundo componente da lista kGrupo,
> # que é uma matriz, usamos
> kGrupo[2]
$centers
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1     5.006000    3.428000     1.462000    0.246000
2     6.850000    3.073684     5.742105    2.071053
3     5.901613    2.748387     4.393548    1.433871

> # Para ver apenas os componentes desta matriz:
> kGrupo[[2]]
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1     5.006000    3.428000     1.462000    0.246000
2     6.850000    3.073684     5.742105    2.071053
3     5.901613    2.748387     4.393548    1.433871

> # O mesmo resultado seria obtido por kGrupo$centers
> # Para listar a primeira linha da matriz
> kGrupo[[2]][,1]
       1        2        3
5.006000 6.850000 5.901613
> # Para listar a primeira coluna da matriz
> kGrupo[[2]][1,]
Sepal.Length  Sepal.Width Petal.Length  Petal.Width
       5.006        3.428        1.462        0.246
> # Para listar o primeiro elemento da primeira linha
> kGrupo[[2]][1,1]
[1] 5.006
> # que é o mesmo que kGrupo$centers[1,1]

Funções em R

Quase tudo em R é uma função. Até os operadores comuns são funções. A declaração 2 + 3 é, na verdade, uma forma sintética para "+"(2, 3).

> '+'(2,3)
[1] 5
> "*"(13, 9)
[1] 117

Em funções, parâmetros são passados por valor e não por referência. Isso significa que um objeto passado como parâmetro é copiado e a cópia passada para a função. O objeto original não é alterado. Além disso variáveis definidas no corpo de funções são locais e não podem ser usadas fora dela. Para tornar globa uma variável usada dentro de uma função podemos usar o operador de "super atribuição" <<-. Considere, por exemplo, o código abaixo.

> f <- function(x) x <- x^2
> u <- c(1,2,3)
> v <- f(u)
> v
[1] 1 4 9
> u
[1] 1 2 3

> #  x é local à função
> print(x)
Error: object 'x' not found

> # Se necessário tornar x global fazemos

> f <- function(x) x <<- x^2
> v <- f(x)
> x
[1] 1 4 9

Funções podem ser usadas recursivamente (ou sejam, podem fazer chamadas a si mesmas). Dois exemplos são mostrados abaixo: o primeiro calcula o fatorial de um inteiro, o segundo exibe a sequência de Fibonacci com n elementos.

> fatorial <- function(x) {
     if (x == 0) return (1)
     else return (x * fatorial(x-1))
 }
> fatorial(0)
[1] 1
> fatorial(6)
[1] 720

> # Obs.: a mesma função poderia ser definida em forma mais compacta como
> fatorial <- function(x) ifelse (x == 0, 1, x * fatorial(x-1))

> # A sequência de Fibonacci:
> fibonacci <- function(n) {
     if(n <= 0)  return("Nada")
     fib <- function(m) ifelse(m <= 1, m, fib(m-1) + fib(m-2))
     seq <- c(0)
     if (n>1) { for(i in 1:(n-1)) seq[i+1] <- fib(i) }
     print("Sequência de Fibonacci:")
     print(seq)
 }
 > fibonacci(9)
[1] "Sequência de Fibonacci:"
[1]  0  1  1  2  3  5  8  13  21

Funções apply(), lapply(), sapply(), tapply()

A função apply() recebe como argumentos uma coleção de objetos (data frame, lista, vetor, etc.), o parâmetro MARGIN (que informa onde será aplicada a função) e uma função (qualquer função pode ser usada). Ela serve para executar alguma operação sobre essa coleção. Seu objetivo é principalmente o de evitar o uso de laços ou loops. Ela tem a seguinte estrutura:

apply(X, MARGIN, FUN)
onde:
x: uma matriz ou array
MARGIN=n : onde n = 1 ou 2, definindo onde a função será aplicada:
se n=1: a função será aplicada nas linhas
se n=2: função aplicada nas colunas
se n=c(1,2): função aplicada nas linhas e colunas
FUN: define função a ser usada.
Podem ser funções internas (mean, median, sum, min, max, ...)
ou definidas pelo usuário
> # Usando a matriz v, já definida:
> print(v)
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
> # A média das colunas
> apply(v,2,mean)
[1]  2  5  8 11
> # A soma das colunas
> apply(v,2,sum)
[1]  6 15 24 33
> minimosNasLinhas <- apply(v, 1, min)
> print(minimosNasLinhas)
[1] 1 2 3

A função lapply() recebe como argumentos uma coleção de objetos (data frame, lista, etc.) e uma função. Ela executa a função sobre todos os elementos da coleçao e retorna um objeto do tipo lista:

lapply(X, FUN)
onde:
X: vetor, lista, data frame, ...
FUN: Função a ser aplicada a cada elemento de X
Podem ser funções internas ou definidas pelo usuário

Para exemplificar aplicaremos a função tolower() para reduzir a letras minúsculas todas as palavras de um vetor de caracteres:

> partes <- c("RODAS","MOTOR","CARBURADOR","PNEUS")
> partesMinuscula <- lapply(partes, tolower)
> print(partesMinuscula)
[[1]]
[1] "rodas"
[[2]]
[1] "motor"
[[3]]
[1] "carburador"
[[4]]
[1] "pneus"

> # Esta lista pode ser convertida em um vetor usando-se unlist:
> partesMinuscula <- unlist(partesMinuscula)
> print(partesMinuscula)
[1] "rodas"      "motor"      "carburador" "pneus"

A função sapply() recebe como argumentos uma coleção de objetos (data frame, lista, etc.) e uma função. Ela age da mesma forma que lapply() mas retorna um vetor ou uma matriz:

sapply(X, FUN)
onde:
X: vetor, lista, data frame, ...
FUN: Função a ser aplicada a cada elemento de X
Podem ser funções internas ou definidas pelo usuário

Usaremos a função sapply() com o data frame cars que traz uma coleção de observações sobre velocidades e distâncias percorridas até repouso em cada velocidade em automóveis (em 1920) para encontrar os valores mínimos em cada coluna:

> # para ver a estrutura do data frame:
> str(cars)
 'data.frame':	50 obs. of  2 variables:
  $ speed: num  4 4 7 7 8 9 10 10 10 11 ...
  $ dist : num  2 10 4 22 16 10 18 26 34 17 ...
> lMinimos <- lapply(cars, max)
> sMinimos <- sapply(cars, max)
> print(lMinimos)
$speed
[1] 25
$dist
[1] 120

> print(sMinimos)
speed  dist
   25   120

O exemplo abaixo mostra o uso de lapply() e sapply() junto com uma função do usuário. Ela retorna os valores do data frame que estão abaixo da média em cada coluna. Neste caso elas retornam valores iguais, como se pode ver com o uso de identical():

> abaixoDaMedia <- function(x) {
                   media <- mean(x)
                   return(x[x < media])
                   }
> abaixoDaMedia(c(1,2,3,40,50))
 [1] 1 2 3
> minSapply <- sapply(cars, abaixoDaMedia)
> minLapply <- lapply(cars, abaixoDaMedia)
[1] TRUE
> minSapply
$speed
 [1]  4  4  7  7  8  9 10 10 10 11 11 12 12 12 12 13 13 13 13 14 14 14 14 15
[25] 15 15
$dist
 [1]  2 10  4 22 16 10 18 26 34 17 28 14 20 24 28 26 34 34 26 36 20 26 32 40
[25] 32 40 42 36 32

> # Os valores retornados são iguais (embora em objetos distintos):
> identical(minSapply, minLapply)
 [1] TRUE

A função tapply() calcula um valor usando uma função (mean, median, min, max, ...) sobre os dados de um objeto agrupados para cada valor de uma variável de fator dada.

tapply(X, INDEX, FUN = NULL)
onde:
X: um objeto, geralmente um vetor
INDEX: uma lista contendo fatores
FUN: a função a ser aplicada sobre os elementos de X

Para ilustrar o uso desta função vamos usar o data frame irisCalculamos primeiro a média dos comprimentos de sépalas para todas as espécies. Depois calculamos as médias para cada espécie em separado, setosa, versicolor, virginica.

Em seguida usamos o data frame mtcars para calcular o consumo médio dos carros, agrupados por número de cilindros (cyl = 4, 6, 8) e tipos de transmissão, am = 0 (automático), 1 = (manual).

> attach(iris)
> # O comprimento médio de todas as sépalas é
> mean(Sepal.Length)
[1] 5.843333
> # O comprimento médio das sépalas agrupadas por espécie:
> tapply(Sepal.Length, Species, mean)
    setosa versicolor  virginica
     5.006      5.936      6.588
> detach(iris)
> # Usando mtcars:
> attach(mtcars)
> # O consumo médio para todos os carros é
> mean(mtcars$mpg)
[1] 20.09062
> # O consumo médio dos carros, agrupados por cilindros e tipo de transmissão
> tapply(mpg, list(cyl, am), mean)
       0        1
4 22.900 28.07500
6 19.125 20.56667
8 15.050 15.40000

> # Para efeito de conferência, calculamos a media de mpg para am=0 e cyl=8
> L <- mtcars[cyl==8 & am==0,]
> # L contém apenas carros com  am=0 e cyl=8
> mean(L$mpg)
[1] 15.05
> detach(mtcars)

Lembramos que em R os índices começam em 1 e não 0, como em muitas outras linguagens.

Ambientes (environments) e escopo

R armazena seus objetos em memória RAM dentro de ambientes ou environments. Um environment fica definido por uma lista que associa os nomes dos objetos nele carregados com seus valores. Eles existem principalmente para organizar estes objetos e a forma como R os encontra. Cada ambiente está ligado a um pai (um parent environment) fazendo com que os ambientes formem uma estrutura de árvore que termina no ambiente de nível mais alto que se chama R_EmptyEnv. Quando se inicia uma sessão o R se encontra no ambiente global, global environment, denominado R_GlobalEnv, também chamado de área de trabalho do usuário. Quando o nome de um objeto é invocado em código o interpretador de R busca na lista do ambiente atual, que pode ser visto com a função environment(). Se não encontrado o nome é procurado no ambiente pai, e assim sucessivamente, até que o último é alcançado.

Um novo ambiente pode ser criado com a função new.env() e objetos dentro deste ambiente com a função assign(). Estes objetos podem ser recuperados através da função get() ou da notação ambiente$variavel. A função exists("variavel", envir = ambiente) verifica a existência de variavel no ambiente, enquanto os objetos em um ambiente são listados com ls(ambiente), como se ilustra abaixo:

> environment()                            # exibe ambiente atual
<environment: R_GlobalEnv>
> var <- "este objeto está em Global Env"  # cria objeto em Global_Env
> novoEnv <- new.env()
> assign(var, "novo objeto em novoEnv", env=novoEnv)
> ls()
 [1] "novoEnv" "var"
> var
[1] "este objeto está em Global Env"
> get(var, env=novoEnv)
[1] "novo objeto em novoEnv"

> # A notação de "$" pode ser usada:
> novoEnv$var <- " outro valor para objeto em novoEnv"
> var
[1] " este objeto está em Global_env"
> novoEnv$var
[1] " outro valor para objeto em novoEnv"

> cat("var em global_env -->", var, "\nvar em novoEnv -->", novoEnv$var)
var em global_env --> este objeto está em Global Env
var em novoEnv --> novo objeto em novoEnv

> # Para ver o ambiente pai de novoEnv
> parent.env(novoEnv)
<environment: R_GlobalEnv>
> novoEnv$x <- 1   $ insere nova variável no ambiente
> ls(envir=novoEnv)
[1] "var" "x"
> exists("x", envir = novoEnv)
[1] TRUE

> # Um ambiente pode ser criado como filho de qualquer outro ambiente
> e2 <- new.env(parent = outroEnv)
> parent.env(e2)

> # Uma variável será criada em e2
> e2$teste <- 123
> # e2 é filho de novoEnv que está em R_GlobalEnv
> # A variável teste não será encontrada em R_GlobalEnv (pois reside em um nível abaixo)
> teste
Error: object 'teste' not found
> # O objeto está no ambiente e2
> e2$teste
[1] 123
> # Para testar se um objeto é um ambiente
> is.environment(e2)
[1] TRUE

> # Observe que a variável que contém o ambiente global é .GlobalEnv
> is.environment(.GlobalEnv)
[1] TRUE

> # Seu atributo name é "R_GlobalEnv"
> environmentName(environment())
[1] "R_GlobalEnv"

A função abaixo percorre os ambientes de modo hierárquico à partir de R_GlobalEnv subindo para os pais até o último ambiente, R_EmptyEnv que é o último ambiente, sem pai. A função search() exibe os ambientes na ordem hierárquica, a mesma ordem usada para a procura de um objeto.

> exibirArvore <- function() {
      a <- environment()
      repeat {        
          print(environmentName(a))
          if (environmentName(a) == "R_EmptyEnv") break
          a <- parent.env(a)
     }
 }
> exibirArvore()
[1] ""
[1] "R_GlobalEnv"
[1] "tools:rstudio"
[1] "package:stats"
[1] "package:graphics"
[1] "package:grDevices"
[1] "package:utils"
[1] "package:datasets"
[1] "package:methods"
[1] "Autoloads"
[1] "base"
[1] "R_EmptyEnv"

> # A função environment() permite descobrir em que
> # ambiente está uma função:
> environment(exibirArvore)
<environment: R_GlobalEnv>

> search()
 [1] ".GlobalEnv"        "tools:rstudio"     "package:stats"     "package:graphics" 
 [5] "package:grDevices" "package:utils"     "package:datasets"  "package:methods"  
 [9] "Autoloads"         "package:base" 	

Observe que a primeira chamada à função environmentName(a) retorna um string vazio, que é o nome do ambiente interno à função. Quando uma função é criada ela gera a criação de um ambiente próprio onde ficam as variáveis definidas em seu corpo. Para exemplificar a existência deste ambiente dedicado à definição da função criamos abaixo a função minhaFuncao(x) que retorna outra função que soma x ao seu argumento. O valor de x passado na definição da função não é alterado com uma definição de seu valor fora do corpo da função.

> f <- function() {
          x <- 1
          print(environment())
          print(parent.env(environment()))
 }
> f()
<environment: 0xd31ee80>
<environment: R_GlobalEnv>

> minhaFuncao <- function(x) { function(y) x+y }
> h <- minhaFuncao(100)
> h(10)
[1] 110
> x <- 3
> h(2)
[1] 102
> # Internamente ao ambiente de h, x = 100
> # h vive no ambiente environment(h).
> # Neste ambiente existe apenas a variável:
> ls(environment(h))
[1] "x"

No caso acima o R criou o ambiente "0xd31ee80" que é filho de R_GlobalEnv. A variável x só existe dentro do ambiente da função.

Uma função (e seu ambiente) podem ser colocados em qualquer outro ambiente usando-se a função environment(funcao ) <- outroAmbiente. No exemplo abaixo a variável anos é definida em .GlobalEnv e dentro do corpo da função quantosAnos. Três outras funções são definidas dentro desta primeira: anosLocal (que usa a variável local, a=10), anosGlobal (que usa a variável em globalEnv, a=10). Na execução da função semBusca a variável está localmente definida, a=1 e nenhuma busca é necessária para a sua execução.

> anos <- 100
> quantosAnos <- function() { 
      anos <- 10
      anosLocal <- function() { print( anos + 5 ) } 
      anosGlobal <- function() { print( anos + 5 ) } 
      semBusca <-  function() { anos <- 1; print( anos + 5 ) } 
      environment( anosGlobal ) <- .GlobalEnv 
      anosLocal() 
      anosGlobal()
      semBusca() 
  }
> quantosAnos()
[1] 15
[1] 105
[1] 6

O exemplo abaixo mostra que quando a função f1 é gerada seu ambiente foi armazenado junto com ela. Nele estão as variáveis a=2, b=3. Este ambiente fica inalterado mesmo depois que a variável global a foi alterado.

> funcaoSoma <- function(a, b) {
     f <- function(x) return( x + a + b )
     return( f )
 }
> a <- 2; b <- 3
> f1 <- funcaoSoma(a, b)
> f1(3)
[1] 8
> a <- 4
> f2 <- criarFuncao(a, b)
> f2(3)
[1] 10
> f1(3)
[1] 8
> # Para forçar a permanência de uma variável após
> # a conclusão da função usamos a atribuição "<<-"
> f <- function(){w<-13}
> f()  # não há retorno
> w
Error: object 'w' not found
> f <- function(){w<<-13}
> f()
> w
[1] 13

Para alocar explicitamente variáveis para um determinado ambiente, além da notação de "$" pode ser usado:

> ls(outroEnv) # o ambiente está vazio
character(0)
> with(outroEnv, {a <- 1; txt <- "texto" })
> ls(outroEnv)
[1] "a"   "txt"
> with(outroEnv, {print(a); print(txt)})
[1] 1
[1] "texto"
> # Alternativamente,
> outroEnv$a; outroEnv$txt
[1] 1
[1] "texto"

Se o nome da biblioteca onde está uma função é previamente conhecido é possível evitar a busca pela definição de uma função usando o operador ::. O mesmo procedimento pode ser usado para forçar o uso de uma função específica quando existem outras de mesmo nome definidas. Se o pacote não está carregado o operador ::: pode ser usado.

> x <- c(123, 234, 345, 242, 34, 100)
> stats::sd(x)
[1] 113.9731

> Wilks
Error: object 'Wilks' not found
> stats:::Wilks
> # ... A definição da função é exibida

> # Para verificar o que significa o operador :::
> `:::`
function (pkg, name) 
{
    pkg <- as.character(substitute(pkg))
    name <- as.character(substitute(name))
    get(name, envir = asNamespace(pkg), inherits = FALSE)
}


Decorre do que foi dito que o escopo de uma variável em R é o seguinte: a variável deve estar definida no ambiente local em que é usada ou em algum ambiente pai. Se variáveis com o mesmo nome estão definidas dentro da hierarquia de ambientes será usada aquela que for encontrada primeiro, ou seja, no ambiente de menor posição.

Muitas linguagens de programação não permitem (ou dsencorajam) o uso de variáveis globais pois elas podem tornar tornar o código mais frágil, sujeito a erros. No R elas podem ser usadas e funções podem acessar variáveis em ambientes acima delas. Mas essa não é sempre uma boa prática. Para projetos com algum nível de complexidade é recomendado que se passe todas as variáveis necessárias na definição da função ou se faça uma verificação rigorosa de escopos, oferecendo alternativas para o caso em que essas variáveios estão ausentes ou tenham tipos não apropriados. Caso as variáveis globais sejam usadas é uma boa prática dar a elas nomes identificadores tais como global.var para evitar que conflituem com outras definidas localmente.

Otimização e Pesquisa de Erros (debugging)

É possível pré-compilar uma função usando a biblioteca compiler (e sua função cmpfun()) que gera uma versão em byte-code. Nas linhas abaixo, fizemos uma medida dos tempos gastos nas funções f e sua versão pré-compilada g.

Algumas práticas podem ser aplicadas se um código estiver demorando muito para ser executado. Uma delas consiste em envolver o código a ser verificado com os comandos Rprof() e Rprof(NULL) e depois executar a função summaryRprof() para ver um resumo dos tempos gastos na execução de cada funcão.

> library(compiler)
> f <- function(n, x) { for (i in 1:n) x <- x + (1 + x)^(-1)}
> g <- cmpfun(f)
> medirTempos <- function() {
      Rprof()
      inicio <- Sys.time()
      f(10000000,1)
      duracao1 <- Sys.time() - inicio
      print(duracao1)
      inicio <- Sys.time()
      g(10000000,1)
      duracao2 <- Sys.time() - inicio
      print(duracao2)
      print(duracao1 - duracao2)
      Rprof(NULL)
      summaryRprof()
  }

> # Executamos a função para medir os tempos gastos  
> medirTempos()
Time difference of 1.003972 secs
Time difference of 0.9667881 secs
Time difference of 0.03718424 secs
$by.self
    self.time self.pct total.time total.pct
"f"      1.00    51.02       1.00     51.02
"g"      0.96    48.98       0.96     48.98

$by.total
              total.time total.pct self.time self.pct
"medirTempos"       1.96    100.00      0.00     0.00
"f"                 1.00     51.02      1.00    51.02
"g"                 0.96     48.98      0.96    48.98

$sample.interval
[1] 0.02

$sampling.time
[1] 1.96

A função compilada g é um pouco mais rápida que sua original. Em blocos maiores e mais demorados de código a diferença pode ser significativa.

Quando dados são importados para uma sessão de R sempre é uma boa prática ler apenas os campos necessários. Por exemplo, suponha que se deseje importar dados de uma tabela contido em um arquivo de texto arquivo.txt que contém 5 variáveis, a primeira de caracter e as 4 demais numéricas, mas apenas as duas primeiras serão usadas. A importação seletiva pode ser obtida usando-se o parâmetro colClasses. Colunas associadas com NULL serão ignoradas:

> # Para importar todos os dados usamos:
> dfLeitura <- read.table(arquivo.txt, header=TRUE, sep=',')
> # Seria mais eficiente e rápido selecionar apenas os campos desejados:
> dfLeitura <- read.table(arquivo.txt, header=TRUE, sep=',',
               colClasses=c("character", "numeric", NULL, NULL, NULL))

A execução de uma operação vetorializada é mais ágil do que percorrer um laço sobre os elementos de um vetor ou matriz. Isso é obtido com o uso de funções projetadas para lidar com vetores de forma otimizada. Alguns exemplo na instalação básica são as funções colSums(), colMeans(), rowSums(),
e rowMeans()
. O pacote matrixStats, plyr, dplyr, reshape2, data.table também incluem diversas funções otimizadas para esse tipo de operação.

Para mostrar isso usamos, desta vez, a função system.time(operação) que mede o tempo de execução da operação.

> partes <- 1:100000000
> soma1 <- function(x) print(sum(x))
> soma2 <- function(x) {
     s <- 0
     for (u in x) s <- s + u
     print(s)
 }

> system.time(soma1(partes))
[1] 5e+15
   user  system elapsed 
      0       0       0 
> system.time(soma2(partes))
[1] 5e+15
   user  system elapsed 
  4.775   0.000   4.775 

Em outro exemplo fazemos a soma dos elementos de uma matriz com 1000 colunas e 1000 linhas (portanto com 1 milhão de elementos).

> set.seed(1234)
> # Cria uma matriz 10000 x 10000
> matriz <- matrix(rnorm(100000000), ncol=10000)
> # Cria função para somar elementos de cada coluna
> somar <- function(x) {
           somando <- numeric(ncol(x))
           for (i in 1:ncol(x)) {
               for (k in 1:nrow(x)) {
                   somando[i] <- somando[i] + x[k,i]
               }
           }
  }
> # Executa a função e mede o tempo gasto
> system.time(somar(matriz))
   user  system elapsed 
 17.231   0.000  17.230
> # mede o tempo de execução de colSums  
> system.time(colSums(matriz))
   user  system elapsed 
  0.108   0.000   0.107 

Como vimos o cálculo é realizado aproximadamente 160 vezes mais rapidamente pela função vetorializada. Essa diferença pode ser muito maior, dependendo da situação analisada.

Sempre é mais eficiente inicializar um objeto em seu tamanho final e depois preenchê-lo de que partir de um objeto vazio e ajustar seu tamanho progressivamente.

> set.seed(1234)
> u <- rnorm(1000000)
> uQuadrado <- 0
> system.time(for (i in 1:length(u)) uQuadrado[i] <- u[i]^2)
   user  system elapsed 
  0.361   0.000   0.361

> # Tempo de execução para a mesma operação com
> # a variável inicializada em seu tamenho final   
> rm(uQuadrado)
> uQuadrado <- numeric(length=1000000)
> system.time(for (i in 1:length(u)) uQuadrado[i] <- u[i]^2)
   user  system elapsed 
   0.11    0.00    0.11

> # Usando a função vetorializada
> uQuadrado <- numeric(length=1000000)
> system.time(uQuadrado <- u^2)
   user  system elapsed 
  0.002   0.000   0.001     

A operação é muito mais rápida quando se usa a função vetorializada. Além da exponenciação, as funções adição, multiplicação e outras operações binárias do tipo são todas vetorializadas.

Gerenciamento de memória

Como já mencionado, R mantém em memória RAM todos os seus objetos em uso, o que pode introduzir lentidão ou mesmo a impossibilidade de realizar alguma operação. Mensagens de erro sobre a insuficiência de espaço de memória indicam que o limite foi excedido. Este limite depende, é claro, do hardware usado, do sistema operacional e da compilação de R (a versão de 64 bits é mais eficiente). Para grandes volumes de dados é preciso procurar escrever um código eficiente para acelerar a execução com o eventual armazenando dados em meio externo para diminuir a sobrecarga na memória RAM e através do uso de rotinas estatísticas especializadas, escritas para maximar a eficiência no manipulação de dados.

Para uma programação mais eficiente é recomendável aplicar operações sobre vetores sempre que possível. As funções internas para manipulação vetores, matrizes e listas (tais como ifelse, colMeans e rowSums) são mais eficientes que loops (for e while). Matrizes usam menos recursos que data frames. No uso de read.table() para carregar dados externos para um data frame especifique as opções colClasses e nrows explicitamente, defina comment.char = "" e marque como NULL as colunas não necessárias. Ao ler dados externos para uma matriz, use a função scan().

Como mencionado, sempre que possível crie objetos com seu tamanho final ao invés de aumentar seu tamanho gradualmente, inserindo valores. Teste seu código usando uma amostra de dados menor para otimizá-lo e remover erros. Exclua objetos temporários ou desnecessários usando rm(objeto). Após a remoção use gc() para iniciar a coleta de lixo. Use a função .ls.objects() para listar objetos no espaço de trabalho e encontrar o que ocupa mais memória e o que pode ser removido.

Use as funções Rprof(), summaryRprof() e system.time() para cronometrar o tempo e gasto em cada função e descobrir qual delas você deveria procurar otimizar. Rotinas externas compiladas podem ajudar a acelerar a execução do programa. Com o pacote Rcpp você pode transferir objetos de R para funções C++ e voltar quando são necessárias sub-rotinas otimizadas.

Para volumes de dados for muito grandes existem bibliotecas que incluem a funcionalidade de descarregar dados em bancos de dados externos ou arquivos binários simples e acessar parte deles. Alguns exemplos são:

Biblioteca Descrição
bigmemory grava e acessa matrizes em arquivos no disco.
ff fornece estruturas de dados que podem ser grabadas em disco, agindo como se permanecessem em RAM.
filehash implementa uma base de dados simples tipo chave-valor gravada em disco
ncdf, ncdf4 fornece interface para arquivos Unidata netCDF
RODBC, RMySQL, ROracle, RPostgreSQL, RSQLite acesso aos respectivos DBMS externos.

No que se refere à análise dos dados em grandes volumes estão disponíveis:

Pacotes biglm e speedglm: ajuste de modelos lineares lineares e generalizados para grandes conjuntos de dados de uma maneira eficiente em termos de memória. Incluem as funções lm() e glm() para lidar com grandes conjuntos de dados.

Diversos pacotes oferecem funções para operações sobre grandes matrizes produzidas pelo pacote bigmemory. biganalytics oferece agrupamento k-means, estatísticas de coluna e um wrapper para biglm. O pacote bigrf pode ser usado para se adequar às florestas de classificação e regressão. bigtabulate fornece funcionalidade table(), split() e tapply(). O pacote bigalgebra inclui funções avançadas da álgebra linear.

biglars oferece cálculo de regressão para conjuntos grande, usado juntamente com o pacote ff.

O pacote data.table introduz uma versão melhorada de um data frame, com métodos mais rápidos e eficientes para: agregação de dados; junções de intervalo; adição, modificação e exclusão de colunas por referência (sem cópias). Um data.table pode ser usado em qualquer função que receba um data frame como argumento.

Depuração de Erros (debugging)

Qualquer projeto de programação com algum grau de complexidade está sujeito a erros. Depuração de erros ou debugging é o processo de se encontrar e resolver as falhas no código. Por mais interessante que seja escrever um bloco de código para resolver algum problema, encontrar erros pode ser tedioso e demorado. Existem erros que impedem a execução do código causando a emissão de mensagens de erros. Estes são, em geral, os mais fáceis de se encontrar. Mas também existem situações em que o código roda perfeitamente mas produz resultados inesperados e incorretos.

As táticas de debugging envolvem rodar as linhas de código interativamente verificando o valor das variáveis, testar o efeito sobre um conjunto de dados que produzem resultados conhecidos, análise do fluxo do código e do estado da memória a cada instante da execução.

Na programação em R erros são geralmente causados por digitação incorreta do nome de variáveis ou funções e chamadas à funções com parâmetros de tipo incorretos, inclusive quando objetos importados de fontes externas contém partes que são NULL, NaN ou NA e são passados como parâmetros para funções que não fazem a verificação para a existência desses valores.

Função Efeito
debug() Marca uma função para debugging.
undebug() Desmarca uma função para debugging.
browser() Permite percorrer o código de execução de uma função passo a passo.
trace() Modifica a função para permite a inserção temporária de de código auxiliar.
untrace() Cancela a função anterior e remove o código temporário.
traceback() Imprime a sequência de chamadas a funções que produziram o último erro não capturado.

Durante a depuração com o uso de browser() a tecla executa a linha sob o cursor e passa o foco para a próxima linha. Teclar força a execução até o final da função sem pausas. Digitar exible a pilha de execução (call stack) e interrompe a execução e desloca o foco para o nível imediatamente superior. Também é possível usar comandos como ls(), print() e atribuições no prompt do depurador.

Atualizando R e suas Bibliotecas

A atualização de R pode ser um pouco trabalhosa. Seguem algumas sugestões para usuários de Windows e Linux.

No Windows

Como eu não utilizo o Windows esta opção está mencionada aqui como uma sugestão, que eu não experimentei. Ela foi extraída da página R-statistics blog.

Uma forma possível e prática para atualizar a instalação do R no Windows consiste em usar a biblioteca installr. Para isso a bliblioteca deve ser instalada e executada de dentro do próprio console (ou do Rstudio, ou outra IDE).

> # instalando e carregando a biblioteca
> install.packages("installr")
> require(installr)
> updateR()

A função updateR() iniciará o processo de atualização, verificando se novas versões estão disponíveis. Se a versão instalada for a mais recente a função termina e retorna FALSE. Caso contrário será perguntado se o usuário deseja prosseguir, após a exibição de um sumário das novidades na versão.

Será oferecida ao usuário a opção de copiar as bibliotecas instaladas para a nova versão e, em seguida, a de atualizar estas bibliotecas.

Mac e Linux

A atualização pode ser feita manualmente usando pacotes no website da CRAN.

$ sudo apt-key adv --keyserver keyserver.ubuntu.com
--recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9
$ sudo add-apt-repository
'deb https://cloud.r-project.org/bin/linux/ubuntu bionic-cran35/'
$ sudo apt update
$ sudo apt install r-base

As linhas acima, para cada entrada no prompt, não devem ser quebradas.

Mais informações sobre instalações no Debian, Red Hat, SUSE e Ubuntu no site See CRAN-R Linux.

Para compilar à partir do código fonte consulte a página CRAN-R Installation and Administration.

Atualizando as bibliotecas

Tanto no Windows quanto no Linux para atualizar apenas as bibliotecas que foram instaladas com install.packages() basta usar, no console a função update.packages(). A função perguntará quais as bibliotecas você deseja atualizar. Para executar a atualização de todas elas, sem o prompt de consulta digite update.packages(ask = FALSE).

Além de update.packages() existem as funções old.packages() que informa quais as bibliotecas possuem versões mais atuais nos repositórios versões aplicáveis e new.packages() que procura por novas bibliotecas disponíveis e ainda não instaladas, oferecendo a opção de instalá-las.

Obs.: Pacotes instalados por devtools::install_github() não são atualizados pelos procedimento descritos. No Windows eles podem ser atualizados por installr.

No RStudio

Para atualizar o RStudio use o item de Menu: Help > Check for Updates. Para atualizar as bibliotecas use Menu: Tools > Check for Packages updates.


Aquisição de Dados