<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Mateus Felipe's interests</title>
        <link>https://mateusf.com</link>
        <description>This is my "corner of internet", where I take some tests, document my studies and write about some subjects I like...</description>
        <lastBuildDate>Sat, 07 Sep 2024 14:33:27 GMT</lastBuildDate>
        <docs>https://github.com/mateusfg7/mateusf.com</docs>
        <generator>Feed for Node.js</generator>
        <copyright>All rights reserved 2025, Mateus Felipe.</copyright>
        <item>
            <title><![CDATA[SQL - Structured Query Language #2]]></title>
            <link>https://mateusf.com/blog/post/sql-structured-query-language-2</link>
            <guid>sql-structured-query-language-2</guid>
            <pubDate>Sat, 07 Sep 2024 14:33:27 GMT</pubDate>
            <description><![CDATA[O próximo nível: Visão, procedures e functions.]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/sql-structured-query-language-2/thumbnail" alt=""> # Introdução</p>
<p>Esse artigo é um resumo feito no intuito de servir como fixação dos conteúdos da matéria de <strong>Banco de Dados</strong>, no curso de <a href="https://www.fapam.edu.br/graduacao/project/gestao-de-t-i/"><strong>Gestão da T.I - FAPAM</strong></a> 2º Período.</p>
<p><em>Aulas ministradas pelo professor <a href="https://www.linkedin.com/in/gabriel-r-diniz/"><strong>Gabriel Ribeiro Diniz</strong></a>.</em></p>
<p>Os comandos SQL serão em sua grande maioria voltados ao SGBD <strong>PostgreSQL</strong>, já que é o SGBD estudado no curso.</p>
<h1>Visão (<code>VIEW</code>)</h1>
<p>A "Visão" é uma tabela virtual, na qual os dados não estão fisicamente armazenados. É uma forma de visualizar os dados de uma ou mais tabelas, sem a necessidade de armazenar esses dados em uma tabela física, ela usa dados de tabelas físicas para criar uma tabela virtual, como se fosse um "atalho" para uma consulta complexa nas tabelas físicas.</p>
<p><strong>TABELAS BASE X TABELAS VIRTUAL</strong></p>
<ul>
<li><strong>Tabela Base</strong>: Tuplas (linhas) estão fisicamente armazenadas no banco de dados.</li>
<li><strong>Tabela Virtual</strong>: Somente a estrutura (esquema) da tabela é armazenada no banco de dados, e não as tuplas.</li>
</ul>
<h2>Para que usar visão?</h2>
<p>Deve-se usar visões quando for frequente consultas com junção de várias relações (tabelas), bastando definir estas junções como uma visão e posteriormente consulta-la, na claáusula FROM.</p>
<p>Desse modo, o objetivo principal de uma visão é simplificar as consultas frequentes de dados, ocultando a complexidade dessas consultas SQL.</p>
<h2>Criando uma visão</h2>
<p>Podemos usar o comando <code>CREATE VIEW{:sql}</code> antes de uma consulta convenvional no banco.</p>
<pre><code class="language-sql">CREATE VIEW nome_da_visao AS &#x3C;consulta>;
</code></pre>
<p>Exemplo:</p>
<pre><code class="language-sql">CREATE VIEW vw_contato_cliente AS SELECT id, nome, email, telefone FROM Cliente;
</code></pre>
<p>Fisicamente, os dados em <code>vw_contato_cliente</code> são os mesmos que em <code>Cliente</code>, mas a visão <code>vw_contato_cliente</code> é uma forma mais simples de acessar esses dados.</p>
<p>Após ser criada, uma visão pode ser consultada normalmente, com a cláusula <code>FROM</code>, como se fosse uma tabela base.</p>
<pre><code class="language-sql">SELECT nome, email FROM vw_contato_cliente;
</code></pre>
<p>Sendo assim, se você atualizar os dados da tabela <code>Cliente</code>, a visão <code>vw_contato_cliente</code> também será atualizada, pois ela é uma "referência" para a tabela <code>Cliente</code>.</p>
<p>Outras visões podem ser criadas a partir de visões existentes, e assim por diante (visões sobre visões).</p>
<p>Podemos criar também visões apartir do resultado de múltiplas tabelas. Considere as seguintes tabelas:</p>
<p><strong><code>CIA_AEREA</code></strong></p>
<table>
<thead>
<tr>
<th>Codigo_Cia</th>
<th>Nome</th>
<th>Sede</th>
<th>Presidente</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Varig</td>
<td>Vitória</td>
<td>Raul Sidnei</td>
</tr>
<tr>
<td>2</td>
<td>Air France</td>
<td>Paris</td>
<td>Etoile Arns</td>
</tr>
<tr>
<td>3</td>
<td>Tam</td>
<td>São Paulo</td>
<td>Cida Faria</td>
</tr>
<tr>
<td>4</td>
<td>Gol</td>
<td>Rio de Janeiro</td>
<td>Bia Falcão</td>
</tr>
</tbody>
</table>
<p><strong><code>VOO</code></strong></p>
<table>
<thead>
<tr>
<th>Num_Voo</th>
<th>Tarifa</th>
<th>Partida</th>
<th>Destino</th>
<th>Codigo_Cia*</th>
</tr>
</thead>
<tbody>
<tr>
<td>AF234</td>
<td>726.20</td>
<td>Brasília</td>
<td>Paris</td>
<td>2</td>
</tr>
<tr>
<td>VG893</td>
<td>254.30</td>
<td>BH</td>
<td>RS</td>
<td>1</td>
</tr>
<tr>
<td>AF875</td>
<td>541.00</td>
<td>São Paulo</td>
<td>Paris</td>
<td>2</td>
</tr>
<tr>
<td>VG487</td>
<td>189.40</td>
<td>Brasília</td>
<td>Curitiba</td>
<td>1</td>
</tr>
<tr>
<td>GO142</td>
<td>349.00</td>
<td>RJ</td>
<td>Recife</td>
<td>4</td>
</tr>
<tr>
<td>TA961</td>
<td>99.00</td>
<td>BH</td>
<td>Brasília</td>
<td>3</td>
</tr>
</tbody>
</table>
<p><strong>Exemplo 1</strong> - Recuperar o nome da companhia aérea, e os voos que cada um oferece.</p>
<pre><code class="language-sql">SELECT CA.NOME, V.NUM_VOO FROM VOO V INNER JOIN CIA_AEREA CA
ON V.CODIGO_CIA = CA.CODIGO_CIA;
</code></pre>
<p>Isso vai nos dar o seguinte retorno:</p>
<p><em>resultado da consulta</em></p>
<table>
<thead>
<tr>
<th>Nome</th>
<th>Num_Voo</th>
</tr>
</thead>
<tbody>
<tr>
<td>Varig</td>
<td>VG487</td>
</tr>
<tr>
<td>Varig</td>
<td>VG893</td>
</tr>
<tr>
<td>Air France</td>
<td>AF234</td>
</tr>
<tr>
<td>Air France</td>
<td>AF875</td>
</tr>
<tr>
<td>Tam</td>
<td>TA961</td>
</tr>
<tr>
<td>Gol</td>
<td>GO142</td>
</tr>
</tbody>
</table>
<p>Podemos facilitar essa consulta criando uma "tabela virtual" apartir desse retorno, ou seja, uma visão!</p>
<pre><code class="language-sql">CREATE VIEW vw_voos_por_cia AS
SELECT CA.NOME, V.NUM_VOO FROM VOO V INNER JOIN CIA_AEREA CA
ON V.CODIGO_CIA = CA.CODIGO_CIA;
</code></pre>
<p>Agora é só consultar a visão <code>vw_voos_por_cia</code> que vamos obter o mesmo resultado da nossa primeira consulta:</p>
<pre><code class="language-sql">SELECT * FROM vw_voos_por_cia;
</code></pre>
<p><strong><code>vw_voos_por_cia</code></strong></p>
<table>
<thead>
<tr>
<th>Nome</th>
<th>Num_Voo</th>
</tr>
</thead>
<tbody>
<tr>
<td>Varig</td>
<td>VG487</td>
</tr>
<tr>
<td>Varig</td>
<td>VG893</td>
</tr>
<tr>
<td>Air France</td>
<td>AF234</td>
</tr>
<tr>
<td>Air France</td>
<td>AF875</td>
</tr>
<tr>
<td>Tam</td>
<td>TA961</td>
</tr>
<tr>
<td>Gol</td>
<td>GO142</td>
</tr>
</tbody>
</table>
<p>Podemos também criar visões renomeandos as colunas da tabela base na <em>view</em>, por exemplo:</p>
<p><strong>Sintaxe</strong></p>
<pre><code class="language-sql">CREATE VIEW nome_da_visao (coluna1, coluna2, coluna3, ...) AS &#x3C;consulta>
</code></pre>
<p><strong>Exemplo</strong> - Recuperar o nome da companhia aérea e o número de voos que cada uma oferece. Seguindo o exemplo dos voos, considere as seguintes tabelas:</p>
<pre><code class="language-sql">CREATE VIEW total_voos (cia_aerea, numero_voos) AS
SELECT nome, COUNT(num_voo)
  FROM VOO V INNER JOIN CIA_AEREA CA
  ON V.CODIGO_CIA = CA.CODIGO_CIA
GROUP BY nome;
</code></pre>
<pre><code class="language-sql">SELECT * FROM total_voos;
</code></pre>
<table>
<thead>
<tr>
<th>cia_aerea</th>
<th>numero_voos</th>
</tr>
</thead>
<tbody>
<tr>
<td>Air France</td>
<td>2</td>
</tr>
<tr>
<td>Gol</td>
<td>1</td>
</tr>
<tr>
<td>Tam</td>
<td>1</td>
</tr>
<tr>
<td>Varig</td>
<td>2</td>
</tr>
</tbody>
</table>
<pre><code class="language-sql">SELECT * FROM total_voos WHERE numero_voos >= 2;
</code></pre>
<table>
<thead>
<tr>
<th>cia_aerea</th>
<th>numero_voos</th>
</tr>
</thead>
<tbody>
<tr>
<td>Air France</td>
<td>2</td>
</tr>
<tr>
<td>Varig</td>
<td>2</td>
</tr>
</tbody>
</table>
<h2>Vantagens</h2>
<p>As <em>views</em> sãi uma simplificação das <strong>consultas que são frequente na aplicaçao</strong>, e auxilia no processo de <strong>autorização/segurança</strong>.</p>
<p>Assim, o acesso não será mais à tabela base VOO e sim, à visão criada a partir da tabela VOO.</p>
<h2>Atualização de uma VIEW</h2>
<p>O SGBD não garante que uma visão sempre atualizará. Uma <em>view</em> com uma única tabela de definição é atualizável.</p>
<pre><code class="language-sql">UPDATE &#x3C;nome da visão> SET &#x3C;valores> WHERE &#x3C;condição>;
</code></pre>
<p>As <em>views</em> definidas sobre <strong>múltiplas tabelas</strong> usando junções, <strong>geralemnte não são atualizáveis</strong>.</p>
<p>As <em>views</em> definidas com funções de agrupamente (<code>GROUP BY{:sql}</code>) e agregação (<code>SUM{:sql}</code>, <code>AVG{:sql}</code>, <code>COUNT{:sql}</code>, <code>MAX{:sql}</code>, <code>MIN{:sql}</code>) <strong>não são atualizáveis</strong>.</p>
<p><strong>Considerações</strong>:</p>
<p>A visão <strong>não é montada</strong> no instante de sua <strong>definição</strong>, mas sim no momento em que alguma <strong>consulta</strong> for realizada sobre ela (pois é uma tarefa custosa, em termos de desempenho, manter todas as tuplas se elas não estão sendo usadas em nenhuma consulta).</p>
<p>Em outras palavras, <strong>apenas o esquema da visão é armazenado</strong> no banco de dados. Todas as vezes que a visão é consultada, o SGBD calcula quais tuplas seriam retornadas por aquela consulta e exibe na tela.</p>
<p><strong>Exemplo</strong> - Considerando a seguinte visão:</p>
<pre><code class="language-sql">CREATE VIEW vw_voos_sem_tarifa AS
SELECT NUM_VOO, PARTIDA, DESTINO FROM VOO;
</code></pre>
<table>
<thead>
<tr>
<th>num_voo</th>
<th>partida</th>
<th>destino</th>
</tr>
</thead>
<tbody>
<tr>
<td>AF234</td>
<td>Brasília</td>
<td>Paris</td>
</tr>
<tr>
<td>AF875</td>
<td>São Paulo</td>
<td>Paris</td>
</tr>
<tr>
<td>GO142</td>
<td>RJ</td>
<td>Recife</td>
</tr>
<tr>
<td>GO542</td>
<td>Brasília</td>
<td>Belém</td>
</tr>
<tr>
<td>TA961</td>
<td>BH</td>
<td>Brasília</td>
</tr>
<tr>
<td>VG487</td>
<td>Brasília</td>
<td>Curitiba</td>
</tr>
<tr>
<td>VG893</td>
<td>BH</td>
<td>RS</td>
</tr>
</tbody>
</table>
<p>Se tentarmos atualizar essa <em>view</em> diretamente, a tabela base <strong><code>VOO</code></strong> será atualizada, porém o campo <code>Tarifa</code> da tabela <strong><code>VOO</code></strong> terá o valor <code>NULL</code> pois ela não esta sendo referenciada na <em>view</em>.</p>
<h2>Exclusão de uma VIEW</h2>
<p>Podemos usar o comando <code>DROP VIEW{:sql}</code> para excluir uma visão.</p>
<pre><code class="language-sql">DROP VIEW &#x3C;nome_da_visao>;
</code></pre>
<p>Ela ficará disponível até que seja executado o comando para deletá-la. É possível excluir visões quando elas não forem mais necessárias, desta forma elas não farão parte do SGBD.</p>
<p><strong>Exemplo</strong></p>
<pre><code class="language-sql">DROP VIEW vw_voos_por_cia;
DROP VIEW vw_voos_sem_tarifa
</code></pre>
<h2>Alterar o nome da VIEW</h2>
<p>Comando para renomear uma visão:</p>
<pre><code class="language-sql">ALTER VIEW &#x3C;nome_da_visao> RENAME TO &#x3C;novo_nome_da_visao>;
</code></pre>
<p><strong>Exemplo</strong></p>
<pre><code class="language-sql">ALTER VIEW vw_voos_por_cia RENAME TO vw_voos_por_companhia;
</code></pre>
<h2>Mudar o código (consulta) da VIEW</h2>
<p>Comando para alterar o código de uma visão:</p>
<pre><code class="language-sql">CREATE OR REPLACE VIEW &#x3C;nome_da_visao> AS &#x3C;nova_consulta>;
</code></pre>
<p><strong>Exemplo</strong></p>
<pre><code class="language-sql">CREATE OR REPLACE VIEW vw_teste AS
SELECT * FROM VOO
WHERE tarifa >= 500.00;
</code></pre>
<h1>Procedimentos (<code>PROCEDURES</code>)</h1>
<p>As <em>Stored Procedures</em> são rotinas definidas no banco de dados, indentificadas pelo por um nome pelo qual podem ser invocadas. Um procedimento pode executar uma série de de instruções e receber parâmetros.</p>
<p><strong>Para que usar <em>stored procedures</em>?</strong></p>
<p>Muitas vezes é requerido várias consultas e atualizações no DB, o que acarreta um maior consumo de recursos pela aplicação (desempenho, memória, etc.). No caso de aplicações web, isso se torna mais visível, devido a maior quantidade de informações que precisam trafegar pela rede e de requisições ao servidor.</p>
<p>Uma boa forma de contornar e atenuar esses consumo de recurso diretamente pela aplicação, é transferir parte do processamento para o DB. Assim, considerando que as máquinas servidoras geralmente têm configurações de hardware mais robustas (e nada se pode garantir com relação às máquinas clientes), essa pode ser uma "saída" a se considerar.</p>
<p><strong>Usar ou não usar procedures?</strong></p>
<p>Como exemplo para o funcionamento dos <em>Stored Procedures</em>, iremos comparar a execução de uma rotina utilizando e outra não utilizando essa técnica.</p>
<p>Considere o seguinte contexto de uma aplicação comercial:</p>
<ul>
<li>O cliente fez um pedido no qual são inseridos itens</li>
<li>O pedido (bem como os itens) permanecem com status "PENDENTE" até ser confirmado.</li>
<li>O operador confirma o pedido e faz o registro no livro caixa.</li>
</ul>
<p>Até o pedido ser confirmado, nenhum lançamento é feito no livro caixa, então é preciso ter uma rotina de confirmação de pedido, que deve executar as seguintes ações:</p>
<ol>
<li><strong><code>UPDATE{:sql}</code></strong> Atualizar o <em>status</em> do pedido (<strong>fechado, pendente</strong>)</li>
<li><strong><code>UPDATE{:sql}</code></strong> Atualizar o <em>status</em> dos itens do pedido (<strong>vendido, pendente</strong>)</li>
<li><strong><code>INSERT{:sql}</code></strong> Lançar o valor do pedido no caixa (<strong>preço</strong>)</li>
</ol>
<p>Temos então pelo menos 3 instruções de atualiação e/ou inserção. Poderíamos representar essa sitação graficamente pela figura:</p>
<p>Por outro lado, poderíamos agrupar essas três instrulções no corpo de um procedimento e chamá-lo a partir da aplicação uma única vez.</p>
<p>As ações de <code>UPDATE{:sql}</code>/<code>INSERT{:sql}</code>/<code>DELETE{:sql}</code>, apartir daí, ficariam por conta do servidor. A representação gráfica desse modelo é mostrada a seguir (Através do procedimento chamado "CONFIRMAR PEDIDO"):</p>
<h2>Criando uma PROCEDURE</h2>
<p><strong>Sintaxe</strong></p>
<pre><code class="language-sql">CREATE PROCEDURE nome_da_procedure(parametro1 tipo, parametro2 tipo, ...)
LANGUAGE SQL AS
$$
  &#x3C;corpo da procedure>
$$;
</code></pre>
<p>Onde, <code>parametro1</code>, <code>parametro2</code>, ... são os parâmetros que a procedure pode receber (opcionais, caso não ouver, deve se passar parênteses vazios <code>nome_da_procedure()</code>), <code>LANGUAGE SQL</code> indica que a procedure será escrita em SQL, <code>$$</code> é um delimitador de bloco de código e <code>&#x3C;corpo da procedure></code> é o código SQL que será executado.</p>
<p><strong>Exemplo</strong></p>
<pre><code class="language-sql">CREATE PROCEDURE insert_cliente(nome VARCHAR(39), cpf VARCHAR(11), celular VARCHAR(11))
LANGUAGE SQL AS
$$
  INSERT INTO CLIENTE (nome, cpf, celular)
  VALUES ((SELECT MAX(codigo_cliente) + 1 FROM cliente), nome, cpf, celular);
$$;
</code></pre>
<p>Tendo criado a <em>procedure</em>, chamá-lo é bastante simples. Para fazer isso fazemos o uso da palavra reservada CALL, como mostra o código a seguir:</p>
<pre><code class="language-sql">CALL &#x3C;nome procedimento>(&#x3C;parâmetros>);
</code></pre>
<p><strong>Exemplo</strong></p>
<pre><code class="language-sql">CALL insert_cliente('Mateus Felipe', '00000000000', '37999999999');
</code></pre>
<h2>Atualizando PROCEDURES</h2>
<p>Para atualiza o código de uma procedure, basta usar o comando <code>CREATE OR REPLACE PROCEDURE{:sql}</code>.</p>
<pre><code class="language-sql">CREATE OR REPLACE PROCEDURE update_preco(novo_preco NUMERIC, codigo_produto INTEGER)
LANGUAGE SQL AS
$$
  UPDATE PRODUTO SET preco = novo_preco WHERE codigo_produto = codigo_produto;
$$;
</code></pre>
<h2>Excluindo PROCEDURES</h2>
<p>Assim como outras estruturas no banco de dados, para exclusão de procedures basta fazer:</p>
<p><strong>Sintaxe</strong></p>
<pre><code class="language-sql">DROP PROCEDURE nome_da_procedure;
</code></pre>
<p><strong>Exemplo</strong></p>
<pre><code class="language-sql">DROP PROCEDURE insert_cliente;
DROP PROCEDURE update_preco;
</code></pre>
<h1>Funções (<code>FUNCTIONS</code>)</h1>
<p>Funções (<em>Function</em>) são rotinas definidas no banco de dados, identificadas por um nome, pelo qual podem ser invocadas, parecidos com uma <em>procedure</em>, recebendo parâmetros, executando instruções, mas com o diferencial de que uma função <strong>sempre retorna um valor</strong>.</p>
<p>Outro diferencial das funções em relação aos procedimentos, é que ela não precisa da palavra resrvada <code>CALL</code> para ser invocada, basta chamar a função no meio de uma consulta SQL.</p>
<p><strong>Sintaxe</strong></p>
<pre><code class="language-sql">CREATE FUNCTION nome_da_funcao(parametro1 tipo, parametro2 tipo, ...)
RETURNS tipo_retorno
LANGUAGE plpgsql AS
$$
  DECLARE
    -- declaração de variáveis
  BEGIN
    -- lógica
  END;
$$;
</code></pre>
<p><strong>Exemplo</strong></p>
<pre><code class="language-sql">CREATE FUNCTION getNumeroFilmes(dataInicial DATE, dataFinal DATE)
RETURNS INTEGER
LANGUAGE plpgsql AS
$$
  DECLARE
    contadorFilmes INTEGER;
  BEGIN
    SELECT COUNT(*) INTO contadorFilmes FROM FILME
    WHERE data_lancamento BETWEEN dataInicial AND dataFinal;

    RETURN contadorFilmes;
  END;
$$;
</code></pre>
<p><strong>Observações</strong></p>
<p>A declaração de novas variáveis pode ser necessária no corpo da função!</p>
<p>Tendo criado a funcion, como executa-la? Como na maioria das vezes haverá um tipo de retorno, a chamada da mesma poderá ser feita <strong>após o <code>SELECT{:sql}</code></strong>, ou <strong>após a cláusula <code>WHERE{:sql}</code></strong>, sendo, para este último caso, o valor retornado deve ser comparado a alguma condição.</p>
<p><strong>Exemplo</strong></p>
<pre><code class="language-sql">SELECT contar_filmes('AÇÃO') FROM Filmes;
</code></pre>
<pre><code class="language-sql">SELECT * FROM Filmes
WHERE tipo = pegar_tipo_com_mais_filmes();
</code></pre>
<h2>Atualizando FUNÇÕES</h2>
<p>Para atualizar o código de uma função, basta usar o comando <code>CREATE OR REPLACE FUNCTION{:sql}</code>.</p>
<pre><code class="language-sql">CREATE OR REPLACE FUNCTION getNumeroFilmes(dataInicial DATE, dataFinal DATE)
RETURNS INTEGER
LANGUAGE plpgsql AS...
</code></pre>
<h2>Excluindo FUNÇÕES</h2>
<p>Para exclusão de funções, basta fazer:</p>
<p><strong>Sintaxe</strong></p>
<pre><code class="language-sql">DROP FUNCTION nome_da_funcao;
</code></pre>
<p><strong>Exemplo</strong></p>
<pre><code class="language-sql">DROP FUNCTION getNumeroFilmes;
</code></pre>
<h1>Gatilhos (<code>TRIGGER</code>)</h1>
<p><em>Triggers</em> são objetos do banco de dados que, relacionados a certa tabela, permitem a realização de processamentos em consequência de uma dererminada ação sobre a tabela.</p>
<p>As <em>triggers</em> são uma forma de automatizar certas ações com base em eventos ocorridos. Podem ser executadas <strong>antes</strong> <code>BEFORE{:sql}</code> ou <strong>depois</strong> <code>AFTER{:sql}</code> de uma operação de <strong>inserção</strong> <code>INSERT{:sql}</code>, <strong>atualização</strong> <code>UPDATE{:sql}</code> ou <strong>exclusão</strong> <code>DELETE{:sql}</code> de registros.</p>
<p>Em aplicações que utilizam banco de dados, que ações sejam disparadas em resposta como consequência de outras, realizando operações de cálculo, validação e, em geral, surtindo alterações na base de dados <strong>automaticamente</strong>.</p>
<p><strong>VANTAGENS</strong>:</p>
<ul>
<li>Parte do processo que seria executado pela aplicação (sistema/software) passa para o banco de dados, poupando recursos da máquina cliente.</li>
<li>Facilita a manutenção, sem que seja necessário alterar o código da aplicação.</li>
</ul>
<p><strong>SINTAXE</strong>:</p>
<pre><code class="language-sql">CREATE TRIGGER &#x3C;Nome do gatilho>
&#x3C;Momento> &#x3C;Evento> ON nome_da_tabela
FOR EACH ROW EXECUTE FUNCTION &#x3C;Funcao>;
</code></pre>
<p><strong>Momento</strong> aqui se refere a quando a trigger será executada, podendo ser <code>BEFORE{:sql}</code> (antes) ou <code>AFTER{:sql}</code> (depois) de um evento. O <strong>evento</strong> é a operação que dispara a trigger, podendo ser <code>INSERT{:sql}</code> (inserção), <code>UPDATE{:sql}</code> (atualização) ou <code>DELETE{:sql}</code> (deleção).</p>
<p>Mas antes de criarmos a <em>trigger</em> de fato, precisamos criar a função que será executada pela <em>trigger</em>. Aqui, reaproveitaremos o conteúdo passado no tópico anterior sobre <a href="#fun%C3%A7%C3%B5es-functions">Funções</a>, introduzindo alguns conceitos novos.</p>
<p>Primeiro vamos pegar uma função a ser executada pela <em>trigger</em> em um <code>UPDATE{:sql}</code>, e explicar os elementos que a compõem.</p>
<p>Exemplo de uma function que possui os elementos OLD e NEW:</p>
<pre><code class="language-sql">CREATE OR REPLACE FUNCTION atualizar_preco()
RETURNS TRIGGER
LANGUAGE plpgsql AS
$$
BEGIN
  IF NEW.preco &#x3C;> OLD.preco THEN
    INSERT INTO HISTORICO_PRECO (codigo_produto, preco_antigo, preco_novo)
    VALUES (NEW.codigo_produto, OLD.preco, NEW.preco);
  END IF;
  RETURN NEW;
END;
$$;

CREATE TRIGGER trigger_atualizar_preco
BEFORE UPDATE ON PRODUTO
FOR EACH ROW EXECUTE FUNCTION atualizar_preco();
</code></pre>
<p>Essa é uma função que será executada antes de uma atualização na tabela <strong><code>PRODUTO</code></strong>. O que ela faz é verificar se o preço novo é diferente do preço antigo, e se for, insere um registro no histórico de preços.</p>
<p><strong>Elementos</strong>:</p>
<ul>
<li><strong><code>OLD</code></strong>: refere-se ao valor antigo da linha que está sendo atualizada.</li>
<li><strong><code>NEW</code></strong>: refere-se ao valor novo da linha que está sendo atualizada.</li>
<li><strong><code>RETURN NEW</code></strong>: é necessário para que a atualização seja efetivada.</li>
<li><strong><code>IF NEW.preco &#x3C;> OLD.preco THEN</code></strong>: é uma condição que verifica se o preço novo é diferente do preço antigo. Se for, é feito um registro no histórico de preços.</li>
<li><strong><code>INSERT INTO HISTORICO_PRECO</code></strong>: é a instrução que insere o registro no histórico de preços.</li>
</ul>
<h2>Excluindo TRIGGERS</h2>
<p>Para exclusão de <em>triggers</em>, basta fazer:</p>
<pre><code class="language-sql">DROP TRIGGER nome_da_trigger;
</code></pre>
<h1>Fontes</h1>
<ul>
<li>Slides das aulas do professor Gabriel Ribeiro Diniz.</li>
<li><a href="https://github.com/GuiLhermeoliveiraf/GTI-FAPAM/blob/main/2%C2%B0%20Per%C3%ADodo/Banco%20de%20Dados%202/Trigger.md">Trigger.md</a> por <a href="https://github.com/GuiLhermeoliveiraf">Guilherme Guimarães Oliveira</a></li>
</ul>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>sql</category>
            <category>dml</category>
            <category>database</category>
            <category>fapam</category>
            <category>gti</category>
            <category>postgres</category>
            <category>visao</category>
            <category>procedures</category>
            <category>functions</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/sql-structured-query-language-2/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Entendendo ancoras do YAML no Docker Compose]]></title>
            <link>https://mateusf.com/blog/post/entendendo-ancoras-do-yaml-no-docker-compose</link>
            <guid>entendendo-ancoras-do-yaml-no-docker-compose</guid>
            <pubDate>Fri, 09 Aug 2024 14:27:49 GMT</pubDate>
            <description><![CDATA[Tradução do post "Understanding YAML Anchors and Aliases in Docker Compose"]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/entendendo-ancoras-do-yaml-no-docker-compose/thumbnail" alt=""> # Introdução</p>
<p>Docker Compose é uma ferramenta popular para definir regras e rodar múltiplos containers Docker de ume vez. Um arquivo Docker Compose é escrito em YAML, um padrão de serialização de dados legível para humanos. Um dos recursos menos conhecidos do YAML — <em>e por tabela do Docker Compose</em> — é a habilidade de usar âncoras e alias para reusar partes de um documento YAML. Esse post vai se aprofundar na compreesão desses conceitos.</p>
<h1>O básico: Âncoras <code>&#x26;</code> e Alias <code>*</code> no YAML</h1>
<p>O YAML permite um truque bacana chamado “anchoring” que, em essência, permite que você crie uma referência ou “âncora” para qualquer valor ou sequência. Uma vez ancorado, esse valor pode ser referenciado em outro lugar no documento YAML usando o que é chamado de “alias”.</p>
<p><strong>Ancoragem (<code>&#x26;</code>)</strong>: Este é o ato de marcar uma chave, valor ou sequência com um identificador, efetivamente criando uma “referência nomeada”.</p>
<p><strong>Aliasing (<code>*</code>)</strong>: Depois de criar uma âncora, você pode se referir a ela usando um alias.</p>
<pre><code class="language-yaml">defaults: &#x26;default_config
  timeout: 10
  retries: 3

connection1:
  &#x3C;&#x3C;: *default_config
  url: http://example.com

connection2:
  &#x3C;&#x3C;: *default_config
  url: http://another.example.com
</code></pre>
<p>No YAML acima, <code>connection1</code> e <code>connection2</code> usam as configurações definidas na chave <code>defaults</code>.</p>
<h1>Aplicando âncoras e aliases no Docker Compose</h1>
<p>O poder real desse recurso YAML se torna evidente quando o aplicamos aos arquivos do Docker Compose, onde frequentemente encontramos blocos repetidos de configuração.</p>
<p>Suponha que temos dois serviços que compartilham algumas configurações comuns, mas têm mapeamentos de porta exclusivos:</p>
<pre><code class="language-yaml">x-shared-configuration: &#x26;shared-config
  image: my-app-image
  environment:
    - MY_ENV=VALUE

services:
  service1:
    &#x3C;&#x3C;: *shared-config
    ports:
      - "8080:8080"
  
  service2:
    &#x3C;&#x3C;: *shared-config
    ports:
      - "8081:8081"
</code></pre>
<p>Ao usar a chave merge <code>&#x3C;&#x3C;</code>, dizemos ao YAML para pegar todos os pares de chave-valor do nosso mapeamento ancorado e adicioná-los ao mapeamento atual. Isso pode reduzir significativamente a redundância em nossos arquivos Docker Compose, tornando-os mais concisos e legíveis.</p>
<h1>Quando usar âncoras e aliases</h1>
<p>Aqui estão alguns casos ao considerar esse recurso no Docker Compose:</p>
<p><strong>Configuração compartilhada</strong>: conforme demonstrado, quando vários serviços compartilham configurações comuns, a ancoragem ajuda a evitar repetições.</p>
<p><strong>Serviços de modelo</strong>: se você tem uma configuração de serviço base e deseja criar variações desse serviço com pequenas diferenças.</p>
<p><strong>Legibilidade</strong>: em arquivos maiores do Docker Compose, blocos repetidos de configurações podem tornar o arquivo mais difícil de navegar. As âncoras podem ajudar a simplificar a estrutura.</p>
<h1>Conclusão</h1>
<p>As âncoras e aliases do YAML oferecem uma maneira eficiente de reutilizar partes de um documento, tornando os arquivos do Docker Compose mais fáceis de manter e legíveis. Esse recurso, embora às vezes esquecido, pode mudar o jogo para aqueles que buscam otimizar seus fluxos de trabalho do Docker. Boa conteinerização!</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>yaml</category>
            <category>docker</category>
            <category>docker-compose</category>
            <category>syntax</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/entendendo-ancoras-do-yaml-no-docker-compose/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[SQL - Structured Query Language]]></title>
            <link>https://mateusf.com/blog/post/sql-structured-query-language</link>
            <guid>sql-structured-query-language</guid>
            <pubDate>Thu, 02 May 2024 14:34:47 GMT</pubDate>
            <description><![CDATA[Introdução à linguagem SQL e seus principais comandos.]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/sql-structured-query-language/thumbnail" alt=""> # Introdução</p>
<p>Esse artigo é um resumo feito no intuito de servir como fixação dos conteúdos da matéria de <strong>Banco de Dados</strong>, no curso de <a href="https://www.fapam.edu.br/graduacao/project/gestao-de-t-i/"><strong>Gestão da T.I - FAPAM</strong></a> 1º Período.</p>
<p><em>Aulas ministradas pelo professor <a href="https://www.linkedin.com/in/gabriel-r-diniz/"><strong>Gabriel Ribeiro Diniz</strong></a>.</em></p>
<p>Os comandos SQL serão em sua grande maioria voltados ao SGBD <strong>PostgreSQL</strong>, já que é o SGBD estudado no curso.</p>
<h1>Linguagem SQL</h1>
<p><strong>SQL</strong> (<strong>S</strong>tructured <strong>Q</strong>uery <strong>L</strong>anguage) é uma linguagem de consulta estruturada, que é usada para manipular e recuperar dados de um banco de dados relacional. SQL é uma linguagem padrão para acessar e manipular bancos de dados.</p>
<p>Tem como base a <strong>álgebra relacional</strong> e o <strong>cálculo relacional</strong>.</p>
<p>O SQL é dividido em três partes principais:</p>
<p><strong>DDL</strong> (Data Definition Language) - <em>Linguagem de Definição de Dados</em><br>
Define esquemas e tabelas, chaves primárias, chaves estrangeiras, exclusão de esquemas, tabelas e colunas, alteração de tabelas.<br>
Diz respeito à <strong>estrutura</strong> das tabelas e esquemas no DB.</p>
<p><strong>DML</strong> (Data Manipulation Language) - <em>Linguagem de Manipulação de Dados</em><br>
Consulta, inserção de dados no DB, exclusão de dados, alteração de dados. Diz respeito aos <strong>dados</strong> das tabelas do BD - CRUD <sup><a href="#user-content-fn-crud" id="user-content-fnref-crud" data-footnote-ref aria-describedby="footnote-label">1</a></sup></p>
<p><strong>DCL</strong> (Data Control Language) - <em>Linguagem de Controle de Dados</em><br>
Define permissões.</p>
<h2>Principais comandos</h2>
<p><strong>DDL</strong> - <strong>Definição</strong> de dados:  <code>CREATE{:sql}</code>, <code>DROP{:sql}</code>, <code>ALTER{:sql}</code>.<br>
<strong>DML</strong> - <strong>Manipulação</strong> de dados: <code>SELECT{:sql}</code>, <code>INSERT{:sql}</code>, <code>UPDATE{:sql}</code>, <code>DELETE{:sql}</code>.<br>
<strong>DCL</strong> - <strong>Controle</strong> de dados: <code>GRANT{:sql}</code>, <code>REVOKE{:sql}</code>.</p>
<h2>Conceitos</h2>
<table>
<thead>
<tr>
<th>Termo</th>
<th>Descrição</th>
</tr>
</thead>
<tbody>
<tr>
<td>Table</td>
<td>Relação (<em>tabela</em>)</td>
</tr>
<tr>
<td>Row</td>
<td>Tupla (<em>linha</em>)</td>
</tr>
<tr>
<td>Column</td>
<td>Atributo (<em>coluna</em>)</td>
</tr>
</tbody>
</table>
<h1>DDL - Data Definition Language</h1>
<p><strong>DDL</strong> - <strong>D</strong>ata <strong>D</strong>efinition <strong>L</strong>anguage (<em>Linguagem de Definição de Dados</em>) é usada para definir a estrutura que armazenará os dados. <strong>Define</strong> a estrutura das tabelas, índices, chaves primárias, chaves estrangeiras, etc.</p>
<h2>Propriedades</h2>
<p>A <strong>DDL</strong> permite não só a especificação de um conjunto de relações (tabelas), como também informações acerca de cada uma das relações, incluindo:</p>
<ul>
<li>O esquema de cada relação (estrutura)</li>
<li>O domínio dos valores associados a cada atributo (<code>int</code>, <code>float</code>, <code>varchar</code>, etc)</li>
<li>As regras de integridade de cada uma das relações
<ul>
<li>O conjunto de índice para manutenção de cada uma das relações</li>
<li>Informações sobre segurança e autoridade sobre cada relação</li>
<li>A estrutura de armazenamento físico de cada relação no disco.</li>
</ul>
</li>
</ul>
<h2>Criar banco de dados/esquema</h2>
<p>Antes de qualquer tabela, é necessário criar um <em>database</em> (banco de dados) ou um <em>schema</em> (esquema). Em SQL uma base de dados (ou esquema) é identificada atravez de um <strong>nome</strong>. Os elementos do esquema incluem tabelas, restrições, etc.</p>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">CREATE DATABASE nome_do_banco;
</code></pre>
<p><em>ou</em></p>
<pre><code class="language-sql">CREATE SCHEMA nome_do_esquema;
</code></pre>
<p><strong>Exemplos</strong>:</p>
<pre><code class="language-sql">CREATE SCHEMA Empresa;
CREATE SCHEMA Universidade;
CREATE DATABASE Hospital;
</code></pre>
<h2>Tipos de domínios</h2>
<h3>Numéricos</h3>
<p><code>INTEGER{:sql}</code>: É um inteiro, originado da palavra <strong><em>integer</em></strong> (em inglês).</p>
<p><code>NUMERIC(p,d){:sql}</code>: É um número de ponto fixo cuja precisão é definida pelo usuário. O número consiste de <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span></span></span></span> dígitos (mais o sinal), sendo que <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>d</mi></mrow><annotation encoding="application/x-tex">d</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">d</span></span></span></span> dos <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span></span></span></span> dígitos estão à direita do ponto decimal.<br>
<strong>Ex.</strong> <code>NUMERIC(4,2){:sql}</code>: <code>42,00</code></p>
<p><code>SERIAL{:sql}</code>: Números inteiros auto incrementados.</p>
<h3>Caracteres (Strings)</h3>
<p><code>CHAR(n){:sql}</code>: É uma cadeia de caracteres de tamanho fixo, com o tamanho <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> definido pelo DBA<sup><a href="#user-content-fn-dba" id="user-content-fnref-dba" data-footnote-ref aria-describedby="footnote-label">2</a></sup>. Abreviação de <strong><em>character</em></strong> (em inglês).<br>
<strong>Ex.</strong> <code>CHAR(12){:sql}</code>: <code>Jack Sparrow</code></p>
<p><code>VARCHAR(n){:sql}</code>: É uma cadeia de caracteres de tamanho variável, com o tamanho <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> definido pelo DBA. Abreviação de <strong><em>character varying</em></strong> (em inglês).</p>
<h3>Booleano</h3>
<p><code>BOOLEAN{:sql}</code>: É um tipo de dado que pode ter um dos dois valores possíveis: <code>TRUE</code> ou <code>FALSE</code> (verdadeiro ou falso).</p>
<h3>Data/Tempo</h3>
<p><code>DATE{:sql}</code>: É um tipo de dado que contém um ano (com 4 dígitos) mês e dia do mês sendo o formato "<strong>aaaa</strong>/<strong>mm</strong>/<strong>dd</strong>" o padrão do <em>MySQL Workbench</em>.</p>
<ul>
<li><strong>ano (date)</strong> - retorna o ano de uma data</li>
<li><strong>Month (date)</strong> - retorna o mês de uma data</li>
<li><strong>Day (date)</strong> - retorna o dia de uma data</li>
</ul>
<p><code>TIME{:sql}</code>: Representa um horário, com o formato "<strong>hh</strong>:<strong>mm</strong>:<strong>ss</strong>" (00:00:00).</p>
<h3>Observações</h3>
<ul>
<li>Uma <strong>chave estrangeira</strong> deve possuir o <strong>mesmo típo de domínio</strong> da <strong>chave primária</strong> correspondente.</li>
<li>O valor <em>nulo</em> <code>NULL{:sql}</code> é um membro de todos os tipos de domínio, isto é, <strong>qualquer atributo</strong> pode receber o valor <code>NULL{:sql}</code> <strong>exceto</strong> aqueles que são <strong>chaves primárias</strong> (<a href="https://mateusf.com/blog/post/mr---modelo-relacional#restri%C3%A7%C3%B5es">restrição de integridade de entidade</a>).</li>
<li>O SQL permite que a declaração de domínio de qualquer atributo inclua a especificação de <code>NOT NULL{:sql}</code> (não nulo), proibindo assim, a inserção de um valor nulo para esse tipo de atributo (obrigatório na <em>PK</em>).</li>
</ul>
<h2>Criar tabela</h2>
<p><code>CREATE TABLE{:sql}</code> define a estrutura de uma tabela, suas restrições de integridade e cria uma tabela vazia.</p>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">CREATE TABLE nome_tabela (...);
</code></pre>
<p><strong>Exemplos:</strong></p>
<pre><code class="language-sql">CREATE TABLE empregado (atributo1 tipo, atributo2 tipo, ...);
</code></pre>
<pre><code class="language-sql">CREATE DATABASE EMPRESA;

CREATE TABLE DEPARTAMENTO (
  CodDep SERIAL NOT NULL,
  NomeDepVARCHAR(30),
  PRIMARY KEY (CodDep)
);

CREATE TABLE FUNCIONARIO (
  Matricula INTEGER NOT NULL,
  Nome VARCHAR(30) NOT NULL,
  Salario NUMERIC(8,2),
  Cargo VARCHAR(15) DEFAULT 'Analista',
  Estado CHAR(2),
  Idade INTEGER, CodDepto INT,
  PRIMARY KEY (Matricula),
  FOREIGN KEY (CodDepto) references DEPARTAMENTO (CodDep) ON DELETE
  NO ACTION ON UPDATE NO ACTION
);
</code></pre>
<p>Criação de um código que gere <strong>códigos automáticos</strong> não e padrão SQL, mas caso seja necessario, pode-se utilizar o <code>SERIAL{:sql}</code> na criação do campo. Muito utilizado em relações que possuiem <strong>ID</strong>s.</p>
<p><strong>Exemplo:</strong></p>
<pre><code class="language-sql">CREATE TABLE cidade (
  id_cidade SERIAL NOT NULL,
  nome_cidade VARCHAR(100) NOT NULL,

  PRIMARY KEY (id_cidade)
);
</code></pre>
<h2>Remover tabela</h2>
<p><code>DROP TABLE{:sql}</code> remove todos os dados e a própria tabela, estando vazia ou não.</p>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">DROP TABLE nome_tabela;
</code></pre>
<p><strong>Exemplo:</strong></p>
<pre><code class="language-sql">DROP TABLE empregado;
</code></pre>
<h2>Alterar tabela</h2>
<p><code>ALTER TABLE{:sql}</code> usado para alterar o esquema da tabela, permite modificar a estrutura de uma tabela existente.</p>
<p>Atributos chave <strong>não podem</strong> ser removidos!<br>
</p>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">ALTER TABLE nome_da_tabela;
</code></pre>
<ol>
<li>Sintaxe básica para <strong>renomear tabela</strong>:</li>
</ol>
<pre><code class="language-sql">ALTER TABLE &#x3C;nome da tabela> RENAME TO &#x3C;novo nome da tabela>;
</code></pre>
<p>Ex.:</p>
<pre><code class="language-sql">ALTER TABLE empregado RENAME TO colaborador;
</code></pre>
<ol start="2">
<li>Sintaxe básica para <strong>inclusão de uma coluna</strong>:</li>
</ol>
<pre><code class="language-sql">ALTER TABLE &#x3C;nome da tabela> ADD COLUMN &#x3C;nome da coluna> &#x3C;domínio e atributos>;
</code></pre>
<p>Ex.:</p>
<pre><code class="language-sql">ALTER TABLE funcionario ADD COLUMN identidade VARCHAR(10);
</code></pre>
<ul>
<li>A instrução <code>ADD COLUMN{:sql}</code> <strong>adiciona uma nova coluna com o valor vazio</strong> para todas as linhas, isto é, <strong>sem nenhum valor</strong> armazenado.</li>
<li>O mesmo acontece quando há a criação de uma tabela (<code>CREATE TABLE{:sql}</code>). A princípio ela não está "povoada" com dados, está vazia, ausente de valores (em outras palavras: <strong>não há linhas/tuplas na tabela</strong>).</li>
<li>Os valores para as diversas linhas devem ser adicionadas através de instruções da <a href="#dml---data-manipulation-language">DML</a> (<a href="#inserir-dados"><code>INSERT INTO</code></a>).</li>
</ul>
<ol start="3">
<li>Sintaxe básica para <strong>exclusão de uma coluna</strong>:</li>
</ol>
<pre><code class="language-sql">ALTER TABLE &#x3C;nome da tabela> DROP &#x3C;nome da coluna>;
</code></pre>
<p>Ex.:</p>
<pre><code class="language-sql">ALTER TABLE funcionario DROP identidade;
</code></pre>
<ol start="4">
<li>Sintaxe básica para <strong>alteração do nome de uma coluna</strong>:</li>
</ol>
<pre><code class="language-sql">ALTER TABLE &#x3C;nom da tabela> RENAME COLUMN &#x3C;nome da coluna> TO &#x3C;novo nome da coluna>;
</code></pre>
<p>Ex.:</p>
<pre><code class="language-sql">ALTER TABLE empregado RENAME COLUMN sexo TO genero;
</code></pre>
<ol start="5">
<li>Sintaxe básica para <strong>alteração do tipo de uma coluna</strong>:</li>
</ol>
<pre><code class="language-sql">ALTER TABLE &#x3C;nome da tabela> ALTER COLUMN &#x3C;nome da coluna> TYPE &#x3C;novo tipo>;
</code></pre>
<p>Ex.:</p>
<pre><code class="language-sql">ALTER TABLE funcionario ALTER COLUMN salario TYPE NUMERIC(10,2);
</code></pre>
<h2>Atributos</h2>
<p><strong>Chave Primária</strong> <code>PRIMARY KEY{:sql}</code>: É um atributo ou conjunto de atributos que identifica unicamente uma tupla em uma relação. A <strong>PK</strong> é um atributo ou conjunto de atributos que <strong>não pode</strong> ter valores repetidos.</p>
<p><strong>Chave Estrangeira</strong> <code>FOREIGN KEY{:sql}</code>: É um atributo ou conjunto de atributos que faz referência a uma chave primária ou única em outra tabela. A <strong>FK</strong> é um atributo ou conjunto de atributos que <strong>pode</strong> ter valores repetidos.<br>
A <strong>FK</strong> pode ser declarada com algumas opções de ação para deleção (<code>ON DELETE{:sql}</code>) e atualização (<code>ON UPDATE{:sql}</code>) de registros:</p>
<ul>
<li><code>CASCADE{:sql}</code></li>
<li><code>SET NULL{:sql}</code></li>
<li><code>SET DEFAULT{:sql}</code></li>
<li><code>RESTRICT{:sql}</code></li>
<li><code>NO ACTION{:sql}</code></li>
</ul>
<p><strong>Restrição de Atributos</strong> (PostgreSQL):</p>
<ul>
<li><code>NOT NULL{:sql}</code> - <strong>NN</strong> - O valor não pode ser nulo.</li>
<li><code>DEFAULT &#x3C;valor>{:sql}</code> - O valor padrão para o atributo caso não seja passado.</li>
<li><code>UNIQUE{:sql}</code> - O valor não pode ser repetido, deve ser único.</li>
</ul>
<h3>Cláusulas da FK</h3>
<h4><code>ON DELETE</code></h4>
<p><strong>Cascata</strong> - <code>CASCADE{:sql}</code></p>
<p>Quando um registro é deletado da tabela referenciada, todos os registros que possuem a chave estrangeira referenciando o registro deletado também são deletados.<br>
Sintaxe:</p>
<pre><code class="language-sql">FOREIGN KEY cpf_cliente REFERENCES Cliente(cpf) ON DELETE CASCADE
</code></pre>
<p>Onde <code>cpf_cliente</code> é o atributo da tabela atual e <code>Cliente(cpf)</code> é a tabela e atributo referenciado.</p>
<p><strong>Restrito</strong> - <code>RESTRICT{:sql}</code></p>
<p>Quando um registro é deletado da tabela referenciada, a operação é restringida (da erro), ou seja, não é permitido deletar o registro pai se houver outros registros filhos á referenciando.<br>
Sintaxe:</p>
<pre><code class="language-sql">FOREIGN KEY cpf_cliente REFERENCES Cliente(cpf) ON DELETE RESTRICT
</code></pre>
<p><strong>Não faz nada</strong> - <code>NO ACTION{:sql}</code> <em>padrão - default</em></p>
<p>Quando um registro é deletado da tabela referenciada, um erro é exibido, e a operação de <code>DELETE{:sql}</code> é revertida.<br>
Sintaxe:</p>
<pre><code class="language-sql">FOREIGN KEY cpf_cliente REFERENCES Cliente(cpf) ON DELETE NO ACTION
</code></pre>
<p><strong>Define como nulo</strong> - <code>SET NULL{:sql}</code></p>
<p>Quando um registro é deletado da tabela referenciada, a chave estrangeira é definida como <code>NULL{:sql}</code>.<br>
Sintaxe:</p>
<pre><code class="language-sql">FOREIGN KEY cpf_cliente REFERENCES Cliente(cpf) ON DELETE SET NULL
</code></pre>
<p><strong>Valor Padrão</strong> - <code>SET DEFAULT{:sql}</code></p>
<p>Quando um registro é deletado da tabela referenciada, a chave estrangeira é definida como o valor padrão <code>DEFAULT{:sql}</code>.<br>
Sintaxe:</p>
<pre><code class="language-sql">FOREIGN KEY cpf_cliente REFERENCES Cliente(cpf) ON DELETE SET DEFAULT
</code></pre>
<h4><code>ON UPDATE</code></h4>
<p><strong>Restrito</strong> - <code>RESTRICT{:sql}</code></p>
<p>Quando um registro é atualizado na tabela referenciada, a operação é restringida (da erro), ou seja, não é permitido atualizar o registro pai se houver outros registros filhos á referenciando.<br>
Sinatxe:</p>
<pre><code class="language-sql">FOREIGN KEY cpf_cliente REFERENCES Cliente(cpf) ON UPDATE RESTRICT
</code></pre>
<p><strong>Define como nulo</strong> - <code>SET NULL{:sql}</code></p>
<p>Quando um registro é atualizado na tabela referenciada de modo que não exista mais a chave primária da tabela alterada, a chave estrangeira é definida como <code>NULL{:sql}</code>.<br>
Sintaxe:</p>
<pre><code class="language-sql">FOREIGN KEY cpf_cliente REFERENCES Cliente(cpf) ON UPDATE SET NULL
</code></pre>
<p><strong>Define como padrão</strong> - <code>SET DEFAULT{:sql}</code></p>
<p>Quando um registro é atualizado na tabela referenciada de modo que não exista mais a chave primária da tabela alterada, a chave estrangeira é definida como o valor padrão <code>DEFAULT{:sql}</code>.<br>
Sintaxe:</p>
<pre><code class="language-sql">FOREIGN KEY cpf_cliente REFERENCES Cliente(cpf) ON UPDATE SET DEFAULT
</code></pre>
<p><strong>Não faz nada</strong> - <code>NO ACTION{:sql}</code> <em>padrão - default</em></p>
<p>Quando um registro é atualizado na tabela referenciada, de modo que a chave primária referenciada não exista mais, um erro é exibido, e a operação de <code>UPDATE{:sql}</code> é revertida.<br>
Sintaxe:</p>
<pre><code class="language-sql">FOREIGN KEY cpf_cliente REFERENCES Cliente(cpf) ON UPDATE NO ACTION
</code></pre>
<h2>Constraits</h2>
<p><em>Constraits</em> são todas as restrições que uma coluna pode ter (<code>PRIMARY KEY{:sql}</code>, <code>FOREIGN KEY{:sql}</code>, <code>NOT NULL{:sql}</code>, <code>UNIQUE{:sql}</code>, etc).</p>
<h3>Adicionar constrait</h3>
<p>Quando preciso adicionar uma <em>constrait</em> em uma coluna de uma tabela <strong>já criada</strong>.</p>
<p><strong>Sintaxe</strong></p>
<pre><code class="language-sql">ALTER TABLE &#x3C;nome da tabela> ADD CONSTRAINT &#x3C;nome da restrição> UNIQUE;
</code></pre>
<pre><code class="language-sql">ALTER TABLE usuario ADD CONSTRAINT email_unico UNIQUE (email);
</code></pre>
<pre><code class="language-sql">ALTER TABLE &#x3C;nome da tabela> ALTER COLUMN &#x3C;nome da coluna> SET NOT NULL;
</code></pre>
<pre><code class="language-sql">ALTER TABLE usuario ALTER COLUMN email SET NOT NULL;
</code></pre>
<pre><code class="language-sql">ALTER TABLE &#x3C;nome da tabela> ALTER COLUMN &#x3C;nome da coluna> SET DEFAULT &#x3C;valor padrão>;
</code></pre>
<pre><code class="language-sql">ALTER TABLE usuario ALTER COLUMN email SET DEFAULT '--';
</code></pre>
<h3>Removendo uma constrait</h3>
<p>Quando é necessário remover uma restrição de uma coluna.</p>
<p><strong>Sintaxe</strong></p>
<pre><code class="language-sql">ALTER TABLE &#x3C;nome da tabela> DROP CONSTRAINT &#x3C;nome da restrição>;
</code></pre>
<pre><code class="language-sql">ALTER TABLE usuario DROP CONSTRAINT email_unico;
</code></pre>
<pre><code class="language-sql">ALTER TABLE &#x3C;nome da tabela> ALTER COLUMN &#x3C;nome da coluna> DROP NOT NULL;
</code></pre>
<pre><code class="language-sql">ALTER TABLE usuario ALTER COLUMN email DROP NOT NULL;
</code></pre>
<pre><code class="language-sql">ALTER TABLE &#x3C;nome da tabela> ALTER COLUMN &#x3C;nome da coluna> DROP DEFAULT;
</code></pre>
<pre><code class="language-sql">ALTER TABLE usuario ALTER COLUMN email DROP DEFAULT;
</code></pre>
<h2>Schemas</h2>
<p><em>Schemas</em> são conjuntos de tabelas dentro do banco de dados. Por padrão, o PostgreSQL cria um <em>schema</em> chamado <code>public</code>, onde todas as tabelas são armazenadas inicialmente. Porém é possível criar <em>schemas</em> personalizados para organizar melhor as tabelas.</p>
<p><strong>Criar <em>schemas</em></strong></p>
<pre><code class="language-sql">CREATE SCHEMA &#x3C;nome_do_schema>;
</code></pre>
<p><em>Exemplo:</em></p>
<pre><code class="language-sql">CREATE SCHEMA empresa;
</code></pre>
<p><strong>Criar tabela em um <em>schema</em></strong></p>
<pre><code class="language-sql">CREATE TABLE &#x3C;nome_do_schema>.&#x3C;nome_da_tabela> (...);
</code></pre>
<p><em>Exemplo:</em></p>
<pre><code class="language-sql">CREATE TABLE empresa.departamento (cod_dep SERIAL, nome_dep VARCHAR(30));
</code></pre>
<p>Toda vez que for necessário referenciar uma tabela em um <em>schema</em> específico, <strong>deve-se informar o nome do <em>schema</em> seguido de um ponto</strong> <code>.{:sql}</code> antes do nome da tabela.</p>
<p>Isso <strong>não ocorre quando a tabela está no <em>schema</em> padrão <code>public</code></strong>. Se não passarmos o nome do <em>schema</em>, o PostgreSQL entende que a tabela está no <em>schema</em> <code>public</code>.<br>
</p>
<p><strong>Remover <em>schemas</em></strong></p>
<pre><code class="language-sql">DROP SCHEMA &#x3C;nome_do_schema>;
</code></pre>
<p><em>Exemplo:</em></p>
<pre><code class="language-sql">DROP SCHEMA empresa;
</code></pre>
<h2>Remover base de dados (DB)</h2>
<p><code>DROP</code> remove toda a base de dados, incluindo todas as tabelas, dados, índices, etc.</p>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">DROP DATABASE nome_do_banco;
</code></pre>
<p><strong>Exemplo:</strong></p>
<pre><code class="language-sql">DROP DATABASE Empresa;
DROP DATABASE Hospital;
DROP DATABASE Universidade;
</code></pre>
<h1>DML - Data Manipulation Language</h1>
<p><strong>DML</strong> - <strong>D</strong>ata <strong>M</strong>anipulation <strong>L</strong>anguage (<em>Linguagem de Manipulação de Dados</em>) é usada para <strong>gerenciar</strong> os dados armazenados em um banco de dados. <strong>Manipula</strong> os dados de uma tabela, como <strong>inserir</strong>, <strong>atualizar</strong>, <strong>excluir</strong> e <strong>selecionar</strong>.</p>
<h2>Propriedades</h2>
<p>A linguagem DML é composta por <strong>4 operações</strong> de manipulação de dados:</p>
<ul>
<li><strong>Inserção</strong> de dados - <code>INSERT{:sql}</code></li>
<li><strong>Exclusão</strong> de dados - <code>DELETE{:sql}</code></li>
<li><strong>Atualização</strong> de dados - <code>UPDATE{:sql}</code></li>
<li><strong>Seleção</strong> de dados (consulta) - <code>SELECT{:sql}</code></li>
</ul>
<h2>Inserir Dados</h2>
<p><code>INSERT INTO{:sql}</code> é usado para inserir novos registros em uma tabela.</p>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">INSERT INTO &#x3C;nome da tabela> (coluna1, coluna2, ...) VALUES (valor1, valor2, ...);
</code></pre>
<p><strong>Exemplo:</strong></p>
<pre><code class="language-sql">INSERT INTO empregado (nome, salario, cargo) VALUES ('João', 2000.00, 'Analista');
</code></pre>
<p>Por exemplo, se criarmos a tabela seguindo a ordem nome-salario-cargo:</p>
<pre><code class="language-sql">CREATE TABLE empregado (
  nome VARCHAR(30),
  salario NUMERIC(8,2),
  cargo VARCHAR(15)
);
</code></pre>
<p>Poderemos inserir omitindo a lista de atributos, dês de que os valores estejam na ordem correta:</p>
<pre><code class="language-sql">INSERT INTO empregado VALUES ('João', 2000.00, 'Analista');
</code></pre>
<pre><code class="language-sql">INSERT INTO empresa.empregado VALUES ('João', 2000.00, 'Analista');
</code></pre>
<h2>Excluir Dados</h2>
<p><code>DELETE FROM{:sql}</code> é usado para excluir registros (tupla/linha) de uma tabela (relação).</p>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">DELETE FROM nome_tabela WHERE condicao;
</code></pre>
<p><strong>Exemplo:</strong></p>
<pre><code class="language-sql">DELETE FROM peca WHERE cod_peca = 200;
</code></pre>
<h2>Atualizar dados</h2>
<p><code>UPDATE{:sql}</code>/<code>SET{:sql}</code> é usado para atualizar registros existentes em uma tabela. <em>Quando há mudança de endereço, nome, etc...</em></p>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">UPDATE nome_tabela SET coluna1 = valor1, coluna2 = valor2 WHERE condicao;
</code></pre>
<p><strong>Exemplo:</strong></p>
<pre><code class="language-sql">UPDATE peca SET preco = 90.00 WHERE cod_peca = 200;
</code></pre>
<h2>Selecionar dados</h2>
<p><code>SELECT{:sql}</code> é usado para selecionar dados de um banco de dados. A instrução <code>SELECT{:sql}</code> é usada para recuperar registros de uma ou mais tabelas.</p>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">SELECT coluna1, coluna2, ... FROM nome_tabela WHERE condicao;
</code></pre>
<p><strong>Exemplo:</strong></p>
<pre><code class="language-sql">SELECT nome_peca, quantidade FROM peca WHERE preco > 50;
</code></pre>
<pre><code class="language-sql">SELECT * FROM peca;
</code></pre>
<h3>Cláusula <code>WHERE</code> (condição)</h3>
<p>A cláusula <code>WHERE{:sql}</code> é usada para <strong>filtrar registros</strong>. A cláusula <code>WHERE{:sql}</code> é usada para extrair apenas os registros que atendem a uma <strong>condição específica</strong>.</p>
<p>Usa <strong>conectores lógicos</strong>:</p>
<ul>
<li><code>AND{:sql}</code> - E</li>
<li><code>OR{:sql}</code> - OU</li>
<li><code>NOT{:sql}</code> - NÃO</li>
</ul>
<p>Usa <strong>operadores de comparação</strong>:</p>
<ul>
<li><code>>{:sql}</code> - Maior</li>
<li><code>&#x3C;{:sql}</code> - Menor</li>
<li><code>={:sql}</code> - Igual</li>
<li><code>&#x3C;={:sql}</code> - Menor ou igual</li>
<li><code>>={:sql}</code> - Maior ou igual</li>
<li><code>!={:sql}</code> - Diferente (<em>ou <code>&#x3C;>{:sql}</code></em>)</li>
<li><code>BETWEEN{:sql}</code> - Entre um intervalo (incluindo os extremos). <em>Facilita a especificação de condições númericas que envolvam um intervalo, ao invés de usar os operadores <code>&#x3C;={:sql}</code> e <code>>={:sql}</code>.</em></li>
</ul>
<h4>Exemplos</h4>
<p>Iremos fazer algumas operações de <strong>busca</strong> <code>SELECT{:sql}</code> usando cláusulas de <strong>condição</strong>/filtro <code>WHERE{:sql}</code> na tabela abaixo:</p>
<table>
<thead>
<tr>
<th>cod_peca</th>
<th>nome_peca</th>
<th>preco</th>
<th>qtd</th>
</tr>
</thead>
<tbody>
<tr>
<td>56</td>
<td>Peça X</td>
<td>23.90</td>
<td>10</td>
</tr>
<tr>
<td>99</td>
<td>Peça Y</td>
<td>56.99</td>
<td>5</td>
</tr>
<tr>
<td>200</td>
<td>Peça Z</td>
<td>80.00</td>
<td>0</td>
</tr>
</tbody>
</table>
<p><strong>EXEMPLO 1</strong> - Selecionar o código e o nome das peças com o preço menor que <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>70.00</mn></mrow><annotation encoding="application/x-tex">70.00</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">70.00</span></span></span></span></p>
<pre><code class="language-sql">SELECT cod_peca, nome_peca FROM peca WHERE preco &#x3C; 70.00;
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>cod_peca</th>
<th>nome_peca</th>
</tr>
</thead>
<tbody>
<tr>
<td>56</td>
<td>Peça X</td>
</tr>
<tr>
<td>99</td>
<td>Peça Y</td>
</tr>
</tbody>
</table>
<p><strong>EXEMPLO 2</strong> - Selecionar o nome e o preço das peças com preço maior que <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>50.00</mn></mrow><annotation encoding="application/x-tex">50.00</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">50.00</span></span></span></span> e menor do que <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>70.00</mn></mrow><annotation encoding="application/x-tex">70.00</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">70.00</span></span></span></span></p>
<pre><code class="language-sql">SELECT nome_peca, preco WHERE preco BETWEEN 50.00 AND 70.00
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>nome_peca</th>
<th>preco</th>
</tr>
</thead>
<tbody>
<tr>
<td>Peça Y</td>
<td>56.99</td>
</tr>
</tbody>
</table>
<p><strong>EXEMPLO 3</strong> - Selecionar todas as informações das peças cuja quantidade em estoque seja maior ou igual a <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>10</mn></mrow><annotation encoding="application/x-tex">10</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">10</span></span></span></span>.</p>
<pre><code class="language-sql">SELECT * FROM peca WHERE qtd >= 10;
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>cod_peca</th>
<th>nome_peca</th>
<th>preco</th>
<th>qtd</th>
</tr>
</thead>
<tbody>
<tr>
<td>56</td>
<td>Peça X</td>
<td>23.90</td>
<td>10</td>
</tr>
</tbody>
</table>
<p><strong>EXEMPLO 4</strong> - Selecionar o código, nome, preço e quantidade de peças no estoque cujo código é <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>200</mn></mrow><annotation encoding="application/x-tex">200</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">200</span></span></span></span>.</p>
<pre><code class="language-sql">SELECT cod_peca, nome_peca, preco, qtd FROM peca WHERE cod_peca = 200;
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>cod_peca</th>
<th>nome_peca</th>
<th>preco</th>
<th>qtd</th>
</tr>
</thead>
<tbody>
<tr>
<td>200</td>
<td>Peça Z</td>
<td>80.00</td>
<td>0</td>
</tr>
</tbody>
</table>
<p><strong>EXEMPLO 5</strong> - Selecionar o nome e a quantidade de todas as peças que há no estoque.</p>
<pre><code class="language-sql">SELECT nome_peca, quantidade FROM peca WHERE qtd != 0;
</code></pre>
<p><em>ou...</em></p>
<pre><code class="language-sql">SELECT nome_peca, quantidade FROM peca WHERE qtd &#x3C;> 0;
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>nome_peca</th>
<th>quantidade</th>
</tr>
</thead>
<tbody>
<tr>
<td>Peça X</td>
<td>10</td>
</tr>
<tr>
<td>Peça Y</td>
<td>5</td>
</tr>
</tbody>
</table>
<h3>Cláusula <code>ORDER BY</code> (ordenação)</h3>
<p>A cláusula <code>ORDER BY{:sql}</code> é usada para <strong>ordenar o resultado</strong> de uma consulta em ordem crescente ou decrescente. Ela é aplicada somente à operações de <strong>consulta</strong> <code>SELECT{:sql}</code>, após a cláusula <code>WHERE{:sql}</code>.</p>
<p>Para especificar a forma de ordenação, devemos indicar</p>
<ul>
<li><code>ASC{:sql}</code> - Crescente <em>padrão - default</em></li>
<li><code>DESC{:sql}</code> - Decrescente</li>
</ul>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">SELECT coluna1, coluna2, ... FROM nome_tabela WHERE condicao ORDER BY coluna ASC|DESC;
</code></pre>
<p><strong>Exemplo:</strong></p>
<pre><code class="language-sql">SELECT nome_peca, quantidade FROM peca ORDER BY nome_peca DESC;
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>nome_peca</th>
<th>quantidade</th>
</tr>
</thead>
<tbody>
<tr>
<td>Peça Z</td>
<td>0</td>
</tr>
<tr>
<td>Peça Y</td>
<td>5</td>
</tr>
<tr>
<td>Peça X</td>
<td>10</td>
</tr>
</tbody>
</table>
<h3>Funções de agregação</h3>
<p>As funções de agregação são usadas para <strong>calcular</strong> algo a partir de um conjunto de valores. As funções de agregação são usadas com a cláusula <code>SELECT{:sql}</code>.</p>
<p>As principais são:</p>
<ul>
<li><code>COUNT{:sql}</code> - Conta o número de linhas (tuplas)</li>
<li><code>SUM{:sql}</code> - Soma os valores da coluna - <em>apenas em dados numéricos</em></li>
<li><code>AVG{:sql}</code> - Calcula a média dos valores da coluna (<em>average</em><sup><a href="#user-content-fn-avg" id="user-content-fnref-avg" data-footnote-ref aria-describedby="footnote-label">3</a></sup>) - <em>apenas em dados numéricos</em></li>
<li><code>MIN{:sql}</code> - Retorna o menor valor da coluna</li>
<li><code>MAX{:sql}</code> - Retorna o maior valor da coluna</li>
</ul>
<p><strong>EXEMPLO 1</strong> - Encontrar a soma dos preços de todas as peças, o maior preço, o menor preço e a média dos preços.</p>
<pre><code class="language-sql">SELECT SUM(preco), MAX(preco), MIN(preco), AVG(preco) FROM peca;
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>SUM(preco)</th>
<th>MAX(preco)</th>
<th>MIN(preco)</th>
<th>AVG(preco)</th>
</tr>
</thead>
<tbody>
<tr>
<td>160.89</td>
<td>80.00</td>
<td>23.90</td>
<td>53.62999999995</td>
</tr>
</tbody>
</table>
<p><strong>EXEMPLO 2</strong> - Contar o número de peças que há no estoque.</p>
<pre><code class="language-sql">SELECT COUNT(*) FROM peca;
</code></pre>
<p><em>ou</em></p>
<pre><code class="language-sql">SELECT COUNT(cod_peca) FROM peca;
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>COUNT(*)</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>3</td>
<td></td>
</tr>
</tbody>
</table>
<h3>Cláusula <code>DISTINCT</code> (linhas únicas)</h3>
<p>Linhas duplicadas podem aparecer nas relações. No caso de desejarmos a eliminação de duplicidade, devemos inserir a palavra <code>DISTINCT{:sql}</code> na cláusula <code>SELECT{:sql}</code>.</p>
<p>Tabela neste momento:</p>
<pre><code class="language-sql">SELECT * FROM peca;
</code></pre>
<table>
<thead>
<tr>
<th>cod_peca</th>
<th>nome_peca</th>
<th>preco</th>
<th>qtd</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Peça A</td>
<td>15.00</td>
<td>10</td>
</tr>
<tr>
<td>2</td>
<td>Peça B</td>
<td>8.00</td>
<td>20</td>
</tr>
<tr>
<td>3</td>
<td>Peça B</td>
<td>8.00</td>
<td>10</td>
</tr>
<tr>
<td>4</td>
<td>Peça A</td>
<td>8.00</td>
<td>30</td>
</tr>
<tr>
<td>5</td>
<td>Peça C</td>
<td>17.00</td>
<td>0</td>
</tr>
<tr>
<td>6</td>
<td>Peça C</td>
<td>17.00</td>
<td>null</td>
</tr>
<tr>
<td>7</td>
<td>Peça A</td>
<td>null</td>
<td>15</td>
</tr>
</tbody>
</table>
<p><strong>Sinatxe:</strong></p>
<pre><code class="language-sql">SELECT DISTINCT coluna1, coluna2, ... FROM nome_tabela;
</code></pre>
<p><strong>Exemplo:</strong></p>
<p><em>Selecionar o nome de todas as peças, sem o <code>DISTINCT{:sql}</code>:</em></p>
<pre><code class="language-sql">SELECT nome_peca FROM peca;
</code></pre>
<table>
<thead>
<tr>
<th>nome_peca</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Peça A</td>
<td></td>
</tr>
<tr>
<td>Peça B</td>
<td></td>
</tr>
<tr>
<td>Peça B</td>
<td></td>
</tr>
<tr>
<td>Peça A</td>
<td></td>
</tr>
<tr>
<td>Peça C</td>
<td></td>
</tr>
<tr>
<td>Peça C</td>
<td></td>
</tr>
<tr>
<td>Peça A</td>
<td></td>
</tr>
</tbody>
</table>
<p><em>Selecionar o nome de todas as peças, com o <code>DISTINCT{:sql}</code>:</em></p>
<pre><code class="language-sql">SELECT DISTINCT nome_peca FROM peca;
</code></pre>
<table>
<thead>
<tr>
<th>nome_peca</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Peça C</td>
<td></td>
</tr>
<tr>
<td>Peça A</td>
<td></td>
</tr>
<tr>
<td>Peça B</td>
<td></td>
</tr>
</tbody>
</table>
<h3>Cláusula <code>GROUP BY</code> (agrupar)</h3>
<p>A cláusula <code>GROUP BY{:sql}</code> é usada para <strong>agrupar linhas</strong> que possuem o mesmo valor em uma ou mais colunas. É normalmente usada em conjunto com funções de agregação para agrupar os resultados de acordo com um ou mais campos. Desta forma, as funções de agregação será aplicada a <strong>cada grupo</strong>, e não a todas as tuplas.</p>
<p>Tabela neste momento:</p>
<pre><code class="language-sql">SELECT * FROM peca ORDER BY nome_peca;
</code></pre>
<table>
<thead>
<tr>
<th>cod_peca</th>
<th>nome_peca</th>
<th>preco</th>
<th>qtd</th>
<th>veiculo</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Peça A</td>
<td>15.00</td>
<td>10</td>
<td>CARRO</td>
</tr>
<tr>
<td>2</td>
<td>Peça B</td>
<td>8.00</td>
<td>20</td>
<td>MOTO</td>
</tr>
<tr>
<td>3</td>
<td>Peça C</td>
<td>8.00</td>
<td>30</td>
<td>CAMINHAO</td>
</tr>
<tr>
<td>4</td>
<td>Peça D</td>
<td>8.00</td>
<td>10</td>
<td>CARRO</td>
</tr>
<tr>
<td>5</td>
<td>Peça E</td>
<td>null</td>
<td>15</td>
<td>CAMINHAO</td>
</tr>
<tr>
<td>6</td>
<td>Peça F</td>
<td>17.00</td>
<td>0</td>
<td>MOTO</td>
</tr>
<tr>
<td>7</td>
<td>Peça G</td>
<td>17.00</td>
<td>null</td>
<td>CARRO</td>
</tr>
</tbody>
</table>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">SELECT coluna1, coluna2, ... FROM nome_tabela GROUP BY coluna1, coluna2, ...;
</code></pre>
<p><strong>EXEMPLO 1</strong> - Selecionar o nome de todas as peças e agrupar por veículo (<em>contar por grupo</em>):</p>
<pre><code class="language-sql">SELECT veiculo, COUNT(1) FROM peca GROUP BY veiculo;
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>veiculo</th>
<th>count</th>
</tr>
</thead>
<tbody>
<tr>
<td>MOTO</td>
<td>2</td>
</tr>
<tr>
<td>CAMINHAO</td>
<td>2</td>
</tr>
<tr>
<td>CARRO</td>
<td>3</td>
</tr>
</tbody>
</table>
<p><strong>EXEMPLO 2</strong> - Obter a soma da quantidade de peças por tipo de veículo</p>
<pre><code class="language-sql">SELECT veiculo, SUM(qtd) FROM peca GROUP BY veiculo;
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>veiculo</th>
<th>sum</th>
</tr>
</thead>
<tbody>
<tr>
<td>MOTO</td>
<td>20</td>
</tr>
<tr>
<td>CAMINHAO</td>
<td>45</td>
</tr>
<tr>
<td>CARRO</td>
<td>20</td>
</tr>
</tbody>
</table>
<h3>Cláusula <code>HAVING</code> (filtro)</h3>
<p>A cláusula <code>HAVING{:sql}</code> é usada para <strong>filtrar grupos</strong> de registros que resultam de uma operação de <code>GROUP BY{:sql}</code>. A cláusula <code>HAVING{:sql}</code> é usada em conjunto com a cláusula <code>GROUP BY{:sql}</code>.</p>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">SELECT coluna1, coluna2, ... FROM nome_tabela GROUP BY coluna1, coluna2, ... HAVING condicao;
</code></pre>
<p><strong>EXEMPLO 2</strong> anterior (<em>alterado</em>) - Obter a soma da quantidade de peças por tipo de veículo que sejam maiores que 20</p>
<pre><code class="language-sql">SELECT veiculo, SUM(qtd) FROM peca GROUP BY veiculo HAVING SUM(qtd) > 20;
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>veiculo</th>
<th>sum</th>
</tr>
</thead>
<tbody>
<tr>
<td>CAMINHAO</td>
<td>45</td>
</tr>
</tbody>
</table>
<h3>Seleção com Junção</h3>
<p>As vezes queremos retornar dados de mais de uma tabela, relacionando os dados de uma tabela com os dados de outra.</p>
<p>Para fazer a junção das tabelas, precisamos definir uma <strong>condição de junção</strong>, na qual os atributos <strong>chave primária</strong> (<em>primary key</em>) e <strong>chave estrangeira</strong> (<em>foreign key</em>) das relações devem ser relacionados.</p>
<p><strong>Tabelas de exemplo</strong></p>
<table>
<thead>
<tr>
<th>num_tec</th>
<th>nome</th>
<th>cargo</th>
</tr>
</thead>
<tbody>
<tr>
<td>297</td>
<td>Marco</td>
<td>Trainee</td>
</tr>
<tr>
<td>553</td>
<td>Hélio</td>
<td>Sênior</td>
</tr>
<tr>
<td>062</td>
<td>Tião</td>
<td>Sênior</td>
</tr>
<tr>
<td>718</td>
<td>Sílvio</td>
<td>Estagiário</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>num_tecnico</th>
<th>tipo</th>
<th>anos_exp</th>
</tr>
</thead>
<tbody>
<tr>
<td>553</td>
<td>Secadora</td>
<td>15</td>
</tr>
<tr>
<td>062</td>
<td>Lavadora</td>
<td>18</td>
</tr>
<tr>
<td>297</td>
<td>Torradeira</td>
<td>1</td>
</tr>
<tr>
<td>297</td>
<td>Secadora</td>
<td>1</td>
</tr>
<tr>
<td>718</td>
<td>Lavadora</td>
<td>5</td>
</tr>
<tr>
<td>062</td>
<td>Congelador</td>
<td>10</td>
</tr>
<tr>
<td>062</td>
<td>Secadora</td>
<td>12</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>tipo</th>
<th>categoria</th>
<th>taxa</th>
</tr>
</thead>
<tbody>
<tr>
<td>Lavadora</td>
<td>1</td>
<td>20,00</td>
</tr>
<tr>
<td>Secadora</td>
<td>1</td>
<td>20,00</td>
</tr>
<tr>
<td>Torradeira</td>
<td>2</td>
<td>10,00</td>
</tr>
<tr>
<td>Congelador</td>
<td>1</td>
<td>8,00</td>
</tr>
<tr>
<td>Batedeira</td>
<td>2</td>
<td>25,00</td>
</tr>
</tbody>
</table>
<p><strong>Exemplo 1:</strong> Obter os nomes dos técnicos com experiência em secadora.</p>
<p><em>Query</em></p>
<pre><code class="language-sql">SELECT nome FROM tecnicos, experiencia
WHERE num_tec = num_tecnico AND tipo = 'Secadora';
</code></pre>
<p><em>Resultado</em></p>
<pre><code class="language-console">| Nome  |
|-------|
| Hélio |
| Tião  |
</code></pre>
<p><strong>Exemplo 2:</strong> Listar o nome dos técnicos e sua experiência em aparelhos da categoria 1</p>
<p><em>Query</em></p>
<pre><code class="language-sql">SELECT tecnicos.nome, experiencia.anos_exp, tipos.tipo
FROM tecnicos, tipos, experiencia
WHERE
  tipos.tipo = experiencia.tipo
AND
  experiencia.num_tecnico = tecnicos.num_tec
AND
  tipos.categoria = 1
</code></pre>
<pre><code class="language-sql">SELECT tecnicos.nome, experiencia.anos_exp, tipos.tipo
FROM tecnicos, tipos, experiencia
WHERE
  tipos.tipo = experiencia.tipo
AND
  experiencia.num_tecnico = tecnicos.num_tec
AND
  tipos.categoria = 1
</code></pre>
<p><em>Resultado</em></p>
<pre><code class="language-console">|  nome  | anos_exp |   tipo    |
|--------|----------|-----------|
| Hélio  |    15    | Secadora  |
| Tião	 |    18    | Lavadora  |
| Marco	 |    1     | Secadora  |
| Sílvio |    5     | Lavadora  |
| Tião	 |    12    | Secadora  |
</code></pre>
<h3>Uso de aliases (apelido)</h3>
<p><em>Alias</em> são <strong>apelidos</strong> que podemos dar aos atributos na hora de retornar valores no <code>SELECT{:sql}</code>, permite associar um "nome de variável" para cada relação, a fim de simplificar comandos SQL, e torna o retorno mais legível.</p>
<p>Para criarmos um <em>alias</em> podemos usar a palavra reservada <code>AS{:sql}</code>. Criando um <code>SELECT{:sql}</code> com <em>alias</em> temos:</p>
<p><em>Alias para tabelas</em></p>
<pre><code class="language-sql">SELECT T.nome, E.anos_exp, TP.tipo
FROM
  tecnicos AS T,
  tipos AS TP,
  experiencia AS E
WHERE TP.tipo = E.tipo
  AND E.num_tecnico = T.num_tec
  AND TP.categoria = 1;
</code></pre>
<p><em>Alias para atributos</em></p>
<pre><code class="language-sql">SELECT
  tecnicos.nome AS Tecnico,
  experiencia.anos_exp AS Experiencia,
  tipos.tipo AS Tipo
FROM tecnicos, tipos, experiencia
WHERE tipos.tipo = experiencia.tipo
  AND experiencia.num_tecnico = tecnicos.num_tec
  AND tipos.categoria = 1;
</code></pre>
<pre><code class="language-txt">nome | anos_exp | tipo         Tecnico | Experiencia | Tipo
-----|----------|------        --------|-------------|------
 ... |   ...    |  ...           ...   |     ...     |  ...
 ... |   ...    |  ...    ->     ...   |     ...     |  ...
 ... |   ...    |  ...           ...   |     ...     |  ...
 ... |   ...    |  ...           ...   |     ...     |  ...
</code></pre>
<h3>Limitando o número de linhas</h3>
<p>Em alguns casos, é necessário limitar o número de linhas retornadas em uma consulta. Para isso, podemos usar a cláusula <code>LIMIT{:sql}</code>.</p>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">SELECT coluna1, coluna2, ... FROM &#x3C;tabela> LIMIT &#x3C;número de linhas>;
</code></pre>
<p><em>Exemplo:</em></p>
<pre><code class="language-sql">SELECT * FROM peca LIMIT 5;
</code></pre>
<h3>Pulando linhas</h3>
<p>Podemos também pular um número de linhas no início da consulta, usando a cláusula <code>OFFSET{:sql}</code>.</p>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">SELECT coluna1, coluna2, ... FROM &#x3C;tabela> OFFSET &#x3C;número de linhas>;
</code></pre>
<p><em>Exemplo:</em></p>
<pre><code class="language-sql">SELECT * FROM peca ORDER BY nome OFFSET 3;
</code></pre>
<h3>Comando <code>LIKE</code></h3>
<p>Quando desejamos pesquisar uma <em>substring</em> de um texto, podemos usar o comando <code>LIKE{:sql}</code> ou <code>NOT LIKE{:sql}</code>. Ele é usado para <strong>comparar</strong> um valor de texto com um <strong>padrão</strong>.</p>
<p>Utilizamos o sinal <code>%{:sql}</code> para representar <strong>zero ou mais caracteres</strong> e o sinal de <code>_{:sql}</code> para representar <strong>um único caractere</strong>.</p>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">SELECT coluna1, coluna2, ... FROM &#x3C;tabela> WHERE coluna LIKE &#x3C;padrão>;
</code></pre>
<p><strong>Exemplo</strong></p>
<p>Imagine que temos a seguinte tabela no banco de dados:</p>
<table>
<thead>
<tr>
<th>cod_pessoa</th>
<th>nome</th>
<th>data_nasc</th>
<th>profissao</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Capitão Jack Sparrow</td>
<td>1710-01-01</td>
<td>Comerciante de rum</td>
</tr>
<tr>
<td>2</td>
<td>Anakin Skywalker</td>
<td>41 ABY</td>
<td>Mestre Jedi</td>
</tr>
<tr>
<td>3</td>
<td>Legolas</td>
<td>87 - 3ª era</td>
<td>Arqueiro</td>
</tr>
<tr>
<td>4</td>
<td>Elliot Alderson</td>
<td>1985-09-17</td>
<td>Engenheiro de segurança</td>
</tr>
<tr>
<td>5</td>
<td>Harvy Specter</td>
<td>1972-03-12</td>
<td>Advogado</td>
</tr>
<tr>
<td>6</td>
<td>Anthony Edward Stark</td>
<td>1970-05-29</td>
<td>Bilionário, playboy, filantropo</td>
</tr>
<tr>
<td>7</td>
<td>Gustavo Fring</td>
<td>1958-04-26</td>
<td>Distribuidor farmacêutico</td>
</tr>
<tr>
<td>8</td>
<td>Batman</td>
<td>1972-02-19</td>
<td>Bruce Wayne</td>
</tr>
</tbody>
</table>
<p>E queremos retornar todoas as pessoas que possuem a letra <code>e</code> no nome.</p>
<pre><code class="language-sql">SELECT * FROM pessoa WHERE nome LIKE '%e%';
</code></pre>
<p><em>Resultado:</em></p>
<pre><code class="language-txt">cod_pessoa | nome            | data_nasc    | profissao
-----------|-----------------|--------------|-----------
3          | Legolas         | 87 - 3ª era  | Arqueiro
4          | Elliot          | 1985-09-17   | Engenheiro de segurança
5          | Harvy Specter   | 1972-03-12   | Advogado
</code></pre>
<h3>Valores condicionais (<code>CASE</code>)</h3>
<p>O comando <code>CASE{:sql}</code> é uma expressão condicional que retorna um valor único com base em uma ou mais condições. Ele é usado para <strong>substituir</strong> valores de uma coluna por outro valor, com base em uma <strong>condição</strong>.</p>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">SELECT coluna1, coluna2, ...,
  CASE
    WHEN condicao1 THEN valor1
    WHEN condicao2 THEN valor2
    ELSE valor_padrao
  END
FROM &#x3C;tabela>;
</code></pre>
<p><em>Exemplo</em></p>
<pre><code class="language-sql">SELECT
  nome,
  idade,
  CASE
    WHEN idade &#x3C; 30 THEN 'Jovem'
    WHEN idade &#x3C; 60 THEN 'Adulto'
    WHEN idade &#x3C; 200 THEN 'Idoso'
    ELSE 'Imortal'
  END AS faixa_etaria
FROM pessoa;
</code></pre>
<pre><code class="language-txt">nome           | idade | faixa_etaria
---------------|-------|-------------
Elliot         | 36    | Adulto
Tony Stark     | 51    | Adulto
Legolas        | 300   | Imortal
Gustavo Fring  | 64    | Idoso
Robbin         | 25    | Jovem
</code></pre>
<h3>Observações</h3>
<p>Uma consulta em SQL pode consistir em até seis cláusulas:</p>
<pre><code class="language-sql">SELECT [*] [DISTINCT] &#x3C;lista de atributos> &#x3C;funções de agregação>
FROM &#x3C;lista de tabelas>
[WHERE &#x3C;condição>]
[GROUP BY &#x3C;lista de atributos para agrupamento>]
[HAVING &#x3C;condição para agrupamento, aceita funções de agregação>]
[ORDER BY &#x3C;lista de atributos para ordenação>] [ASC] [DESC]
</code></pre>
<ul>
<li>Apenas as cláusulas <code>SELECT{:sql}</code> e <code>FROM{:sql}</code> são obrigatórias</li>
<li>Quando existentes, as cláusulas devem aparecer na ordem específica acima.</li>
<li>O <code>ORDER BY{:sql}</code> só pode ser ultilizado após o último <code>SELECT{:sql}</code> (se a linguagem permitir)</li>
<li>As cláusulas <code>GROUP BY{:sql}</code> e <code>HAVING{:sql}</code> só podem ser usadas nos comandos <code>SELECT{:sql}</code> individuais</li>
</ul>
<h2>Retornando dados alterados</h2>
<p>Em alguns caso, é necessário retornar dados que foram alterados (inseridos, atualizados, deletados). Para isso podemos usar a cláusula <code>RETURNING{:sql}</code> ao final da nossa query de alteração.</p>
<p><strong>Sintaxe:</strong></p>
<pre><code class="language-sql">INSERT INTO &#x3C;nome da tabela> (...) VALUES (...) RETURNING coluna1, coluna2, ...;
</code></pre>
<p><em>Exemplo:</em></p>
<pre><code class="language-sql">INSERT INTO peca (nome_peca, preco, qtd)
VALUES ('Peça H', 10.00, 5)
RETURNING cod_peca;
</code></pre>
<pre><code class="language-sql">UPDATE peca SET preco = 90.00
WHERE cod_peca = 200
RETURNING nome_peca;
</code></pre>
<pre><code class="language-sql">DELETE FROM peca WHERE cod_peca = 200 RETURNING nome_peca;
</code></pre>
<p>A sintaxe do <code>RETURNING{:sql}</code> é a mesma que a do <code>SELECT{:sql}</code>, ou seja, podemos retornar qualquer coluna da tabela que foi alterada.</p>
<h2>Valores <code>NULL</code> (nulo)</h2>
<p>Suponhamos que temos a tabela <code>Peça</code> criada anteriormente, estruturada e preenchida da seguinte forma:</p>
<table>
<thead>
<tr>
<th>Coluna (tupla)</th>
<th><em>Data Type</em> (Tipo)</th>
<th><em>Length/Precision</em> (Comprimento)</th>
<th><em>Scale</em> (Escala)</th>
<th><em>Not Null?</em> (Não Nulo?)</th>
<th><em>Primary Key?</em> (Chave Primária?)</th>
<th><em>Default</em> (Padrão)</th>
</tr>
</thead>
<tbody>
<tr>
<td>cod_peca</td>
<td>INTEGER</td>
<td></td>
<td></td>
<td>Sim</td>
<td>Sim</td>
<td></td>
</tr>
<tr>
<td>nome_peca</td>
<td>VARCHAR</td>
<td>30</td>
<td></td>
<td>Sim</td>
<td>Não</td>
<td></td>
</tr>
<tr>
<td>preco</td>
<td>NUMERIC</td>
<td>6</td>
<td>2</td>
<td>Não</td>
<td>Não</td>
<td></td>
</tr>
<tr>
<td>qtd</td>
<td>INTEGER</td>
<td></td>
<td></td>
<td>Não</td>
<td>Não</td>
<td>0</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>cod_peca</th>
<th>nome_peca</th>
<th>preco</th>
<th>qtd</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Peça A</td>
<td>15.00</td>
<td>10</td>
</tr>
<tr>
<td>2</td>
<td>Peça B</td>
<td>8.00</td>
<td>20</td>
</tr>
<tr>
<td>3</td>
<td>Peça C</td>
<td>8.00</td>
<td>30</td>
</tr>
<tr>
<td>4</td>
<td>Peça D</td>
<td>8.00</td>
<td>10</td>
</tr>
</tbody>
</table>
<pre><code class="language-sql">CREATE TABLE peca (
  cod_peca INTEGER NOT NULL,
  nome_peca VARCHAR(30) NOT NULL,
  preco NUMERIC(6,2),
  qtd INTEGER DEFAULT 0
);
</code></pre>
<pre><code class="language-sql">INSERT INTO peca VALUES
  (1, 'Peça A', 15.00, 10),
  (2, 'Peça B', 8.00, 20),
  (3, 'Peça C', 8.00, 30),
  (4, 'Peça D', 8.00, 10);
</code></pre>
<h3>Inserindo valores nulos</h3>
<p>Quando realizamos um <code>INSERT{:sql}</code> e não passamos o campo, o banco de dados vai automaticamente inserir <code>NULL{:sql}</code> no valor da célula.</p>
<pre><code class="language-sql">INSERT INTO peca (cod_peca, nome_peca, qtd) VALUES (5, 'Peça E', 15);
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>cod_peca</th>
<th>nome_peca</th>
<th>preco</th>
<th>qtd</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Peça A</td>
<td>15.00</td>
<td>10</td>
</tr>
<tr>
<td>2</td>
<td>Peça B</td>
<td>8.00</td>
<td>20</td>
</tr>
<tr>
<td>3</td>
<td>Peça C</td>
<td>8.00</td>
<td>30</td>
</tr>
<tr>
<td>4</td>
<td>Peça D</td>
<td>8.00</td>
<td>10</td>
</tr>
<tr>
<td><strong>5</strong></td>
<td><strong>Peça E</strong></td>
<td><em><strong><code>null</code></strong></em></td>
<td><strong>15</strong></td>
</tr>
</tbody>
</table>
<p>Lembre-se que colunas que tem o valor <code>DEFAULT{:sql}</code> definido, não serão preenchidas com <code>NULL{:sql}</code>, mas sim com o valor <code>DEFAULT{:sql}</code> especificado no momento da criação da tabela.</p>
<pre><code class="language-sql">INSERT INTO peca (cod_peca, nome_peca, preco) VALUES (6, 'Peça F', 20.00);
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>cod_peca</th>
<th>nome_peca</th>
<th>preco</th>
<th>qtd</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Peça A</td>
<td>15.00</td>
<td>10</td>
</tr>
<tr>
<td>2</td>
<td>Peça B</td>
<td>8.00</td>
<td>20</td>
</tr>
<tr>
<td>3</td>
<td>Peça C</td>
<td>8.00</td>
<td>30</td>
</tr>
<tr>
<td>4</td>
<td>Peça D</td>
<td>8.00</td>
<td>10</td>
</tr>
<tr>
<td>5</td>
<td>Peça E</td>
<td>null</td>
<td>15</td>
</tr>
<tr>
<td><strong>6</strong></td>
<td><strong>Peça F</strong></td>
<td><strong>20.00</strong></td>
<td><strong><code>0</code></strong></td>
</tr>
</tbody>
</table>
<p>Existe um outra forma de definir um valor como <code>NULL{:sql}</code>. Deixando explícito no comando <code>INSERT{:sql}</code> que a coluna deve receber o valor <code>NULL{:sql}</code>.</p>
<pre><code class="language-sql">INSERT INTO peca (cod_peca, nome_peca, preco, qtd) VALUES (7, 'Peça G', 17.00, NULL);
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>cod_peca</th>
<th>nome_peca</th>
<th>preco</th>
<th>qtd</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Peça A</td>
<td>15.00</td>
<td>10</td>
</tr>
<tr>
<td>2</td>
<td>Peça B</td>
<td>8.00</td>
<td>20</td>
</tr>
<tr>
<td>3</td>
<td>Peça C</td>
<td>8.00</td>
<td>30</td>
</tr>
<tr>
<td>4</td>
<td>Peça D</td>
<td>8.00</td>
<td>10</td>
</tr>
<tr>
<td>5</td>
<td>Peça E</td>
<td>null</td>
<td>15</td>
</tr>
<tr>
<td>6</td>
<td>Peça F</td>
<td>20.00</td>
<td>0</td>
</tr>
<tr>
<td><strong>7</strong></td>
<td><strong>Peça G</strong></td>
<td><strong>17.00</strong></td>
<td>null</td>
</tr>
</tbody>
</table>
<p>Repare que mesmo o campo <code>qtd</code> possuindo um valor <code>DEFAULT{:sql}</code>, foi definido de forma explícita no <code>INSERT{:sql}</code> que essa coluna deveria possuir um valor <code>NULL</code>.</p>
<pre><code class="language-sql">INSERT INTO peca (cod_peca, nome_peca, preco, qtd) VALUES (7, NULL, 17.00, 12);
</code></pre>
<p><em>Resultado:</em></p>
<pre><code class="language-output">ERROR:  null value in column "nome_peca" of relation "peca" violates not-null constraint
DETAIL:  Failing row contains (7, null, 17.00, 12).
SQL state: 23502
</code></pre>
<h3>Selecionando valores nulos</h3>
<p>Caso você queira selecionar somente as linhas com valores nulos em uma determinada célula, a forma correta é utilizar o <code>IS NULL{:sql}</code>, e não <code>... = NULL{:sql}</code>.</p>
<pre><code class="language-sql">SELECT * FROM peca WHERE preco IS NULL;
</code></pre>
<pre><code class="language-sql">SELECT * FROM peca WHERE preco = NULL;
</code></pre>
<h3>Selecionando valores não nulos</h3>
<p>Caso você queira selecionar apenas as linhas que <strong>não possuem</strong> valores nulos em uma determinada coluna, é só utilizar o c omando <code>IS NOT NULL{:sql}</code>.</p>
<pre><code class="language-sql">SELECT * FROM peca WHERE preco IS NOT NULL;
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>cod_peca</th>
<th>nome_peca</th>
<th>preco</th>
<th>qtd</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Peça A</td>
<td>15.00</td>
<td>10</td>
</tr>
<tr>
<td>2</td>
<td>Peça B</td>
<td>8.00</td>
<td>20</td>
</tr>
<tr>
<td>3</td>
<td>Peça C</td>
<td>8.00</td>
<td>30</td>
</tr>
<tr>
<td>4</td>
<td>Peça D</td>
<td>8.00</td>
<td>10</td>
</tr>
<tr>
<td>6</td>
<td>Peça F</td>
<td>20.00</td>
<td>0</td>
</tr>
<tr>
<td>7</td>
<td>Peça G</td>
<td>17.00</td>
<td>null</td>
</tr>
</tbody>
</table>
<p><em>Repare que a peça de código <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>5</mn></mrow><annotation encoding="application/x-tex">5</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">5</span></span></span></span> não foi incluída no resultado, por possuir o valor <code>null</code> na coluna <code>preco</code>.</em></p>
<h3>Ordenando colunas com <code>NULL</code></h3>
<p>Por <em>default</em>, caso você ordene um <code>SELECT{:sql}</code> por uma coluna que possui células com valor <code>NULL{:sql}</code>, essas células serão as <strong>últimas</strong> a serem retornadas.</p>
<pre><code class="language-sql">SELECT * FROM peca ORDER BY preco;
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>cod_peca</th>
<th>nome_peca</th>
<th>preco</th>
<th>qtd</th>
</tr>
</thead>
<tbody>
<tr>
<td>4</td>
<td>Peça D</td>
<td>8.00</td>
<td>10</td>
</tr>
<tr>
<td>2</td>
<td>Peça B</td>
<td>8.00</td>
<td>20</td>
</tr>
<tr>
<td>3</td>
<td>Peça C</td>
<td>8.00</td>
<td>30</td>
</tr>
<tr>
<td>1</td>
<td>Peça A</td>
<td>15.00</td>
<td>10</td>
</tr>
<tr>
<td>6</td>
<td>Peça F</td>
<td>20.00</td>
<td>0</td>
</tr>
<tr>
<td>7</td>
<td>Peça G</td>
<td>17.00</td>
<td>null</td>
</tr>
<tr>
<td>5</td>
<td>Peça E</td>
<td>null</td>
<td>15</td>
</tr>
</tbody>
</table>
<p>Caso você deseje que as células com valores <code>NULL{:sql}</code> sejam as primeiras a serem retornadas no <code>SELECT{:sql}</code>, utilizamos o <code>ORDER BY ... NULLS FIRST{:sql}</code>.</p>
<pre><code class="language-sql">SELECT * FROM peca ORDER BY preco NULLS FIRST;
</code></pre>
<p><em>Resultado:</em></p>
<table>
<thead>
<tr>
<th>cod_peca</th>
<th>nome_peca</th>
<th>preco</th>
<th>qtd</th>
</tr>
</thead>
<tbody>
<tr>
<td>5</td>
<td>Peça E</td>
<td>null</td>
<td>15</td>
</tr>
<tr>
<td>2</td>
<td>Peça B</td>
<td>8.00</td>
<td>20</td>
</tr>
<tr>
<td>3</td>
<td>Peça C</td>
<td>8.00</td>
<td>30</td>
</tr>
<tr>
<td>4</td>
<td>Peça D</td>
<td>8.00</td>
<td>10</td>
</tr>
<tr>
<td>1</td>
<td>Peça A</td>
<td>15.00</td>
<td>10</td>
</tr>
<tr>
<td>6</td>
<td>Peça F</td>
<td>20.00</td>
<td>0</td>
</tr>
<tr>
<td>7</td>
<td>Peça G</td>
<td>17.00</td>
<td>null</td>
</tr>
</tbody>
</table>
<h3>Substituindo valores nulos</h3>
<p>Em alguns casos é necessário substituir os valores <code>NULL{:sql}</code> por outro valor, quando usarmos o <code>SELECT{:sql}</code> ou o <code>RETURNIG{:sql}</code>. Para isso, podemos usar a função <code>COALESCE{:sql}</code>.</p>
<p><strong>Sintaxe</strong></p>
<pre><code class="language-sql">SELECT COALESCE(&#x3C;coluna>, &#x3C;valor substituido>) FROM &#x3C;tabela>;
</code></pre>
<p><em>Exemplo:</em></p>
<pre><code class="language-sql">SELECT codigo, telefone FROM professor;
</code></pre>
<pre><code class="language-txt">| codigo | telefone |
|--------|----------|
|   1    | 37999999 |
|   2    | [null]   |
</code></pre>
<pre><code class="language-sql">SELECT codigo, COALESCE(telefone, 'NÃO CADASTRADO') FROM professor;
</code></pre>
<pre><code class="language-txt">| codigo | telefone       |
|--------|----------------|
|   1    | 37999999       |
|   2    | NÃO CADASTRADO |

</code></pre>
<h2>Junções (Comando <code>JOIN</code>)</h2>
<p>Junção é a possibilidade de se criar relacionamentos entre tabelas, de forma a poder recuperar dados de mais de uma tabela em uma única consulta. Um jeito melhor e nativo de se juntar mais de uma tabela, diferente do método apresentado no capítulo <a href="#sele%C3%A7%C3%A3o-com-jun%C3%A7%C3%A3o">Seleção com Junção</a>.</p>
<p>Isso é possível atravez do comando <code>JOIN{:sql}</code> (<em>junção</em>), que é usado para combinar linhas de duas ou mais tabelas com base em uma relação entre elas, e recuperando esses dados usando apenas um <code>SELECT{:sql}</code>.</p>
<p>É importante utilizá-lo, porque tira da cláusula <code>WHERE{:sql}</code> condições que são estritamente das junções (chave primária igual a chave estrangeira, por exemplo).</p>
<p>Existem as variações de junções <strong>internas</strong> e <strong>externas</strong>.</p>
<p><strong>Internas</strong>: <code>INNER JOIN{:sql}</code> e <code>NATURAL JOIN{:sql}</code><br>
<strong>Externas</strong>: <code>OUTER JOIN{:sql}</code> (<em><code>LEFT{:sql}</code>, <code>RIGHT{:sql}</code>, <code>FULL{:sql}</code></em>)</p>
<p><strong>Como funciona o comando <code>JOIN{:sql}</code>?</strong></p>
<p>Quando um comando <code>SELECT{:sql}</code> especifica campos de duas tabelas <strong>sem nenhumas restrição ou filtro</strong>, o resultado será um número de linhas iguais à multiplicação do total de linhas da primeira tabela (<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span>) pela segunda tabela (<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>M</mi></mrow><annotation encoding="application/x-tex">M</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">M</span></span></span></span>), ou seja <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>M</mi><mo>×</mo><mi>N</mi></mrow><annotation encoding="application/x-tex">M\times N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7667em;vertical-align:-0.0833em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">M</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span>.</p>
<p>Isso ocorre devido ao fato de que, para cada linha da primeira tabela, todas as linhas da segunda são processadas. Operações de junção toma duas relações, e têm como resultado uma outra relação.</p>
<p>Porém, o benefício do <code>JOIN{:sql}</code> só será sentido quando as chaves <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi><mi>K</mi></mrow><annotation encoding="application/x-tex">PK</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mord mathnormal" style="margin-right:0.07153em;">K</span></span></span></span> e <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>F</mi><mi>K</mi></mrow><annotation encoding="application/x-tex">FK</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="mord mathnormal" style="margin-right:0.07153em;">K</span></span></span></span> forem equivalentes, ou seja, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi><mi>d</mi><mo>=</mo><mi>i</mi><mi>d</mi><mi mathvariant="normal">_</mi><mi>c</mi><mi>u</mi><mi>r</mi><mi>s</mi><mi>o</mi></mrow><annotation encoding="application/x-tex">id = id\_curso</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">i</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.0044em;vertical-align:-0.31em;"></span><span class="mord mathnormal">i</span><span class="mord mathnormal">d</span><span class="mord" style="margin-right:0.02778em;">_</span><span class="mord mathnormal">c</span><span class="mord mathnormal">u</span><span class="mord mathnormal">rso</span></span></span></span>, usando a palavra reservada <code>ON{:sql}</code> (<em>será explicado mais a frente</em>).</p>
<p>A operção de junção tem algumas variantes, e cada uma dessas variações consiste em um <em>tipo de junção</em> e uma <em>condição de junção</em>.</p>
<p><strong>Sintaxe</strong></p>
<pre><code class="language-sql">SELECT coluna1, coluna2, ...
FROM tabela1 &#x3C;tipo> JOIN tabela2
ON &#x3C;condição>;
</code></pre>
<p><em>Exemplo</em></p>
<pre><code class="language-sql">SELECT nome, nasc, experiencia
FROM tecnicos INNER JOIN experiencia
ON tecnicos.num_tec = experiencia.num_tecnico;
</code></pre>
<p><strong>TIPO DE JUNÇÃO</strong> (<code>INNER{:sql}</code> ou <code>OUTER{:sql}</code>)<br>
Define como as tuplas em cada relação que não possuam nenhuma conrrespondência com as tuplas da outra relação deve ser tratadas.</p>
<p><strong>CONDIÇAO DE JUNÇAO</strong> (<code>ON{:sql}</code>)<br>
Definem quais tuplas das duas relações apresentam correspondência e quais atributos são apresentados de uma junção.</p>
<h3><code>INNER JOIN</code></h3>
<p>O <code>INNER JOIN{:sql}</code> (Ou somente <code>JOIN{:sql}</code>) é uma <strong>junção interna</strong>, que junta os registros de uma tabela que tiver um <strong>correspondente</strong> na outra tabela, através da chave primária e estrangeira.</p>
<p>Por exemplo, a tabela abaixo é resultado de um <code>JOIN{:sql}</code> de 2 outras tabelas. A segunda tabela possui chaves estrangeiras apontando para valores nulos, e a primeira possui tuplas sem conrrespondência na segunda tabela. O resultado do <code>INNER JOIN{:sql}</code> será apenas as linhas que possuem corrêspondência nas duas tabelas:</p>
<p><strong>Sintaxe</strong></p>
<pre><code class="language-sql">SELECT coluna1, coluna2, ...
FROM (tabela1 INNER JOIN tabela2
      ON tabela1.chave_primaria = tabela2.chave_estrangeira);
</code></pre>
<pre><code class="language-sql">SELECT coluna1, coluna2, ...
FROM (tabela1 JOIN tabela2
      ON tabela1.chave_primaria = tabela2.chave_estrangeira);
</code></pre>
<h4>Usando o <code>INNER JOIN</code> com 2 tabelas</h4>
<p><strong>Exemplo</strong>: Liste o nome dos técnicos que possuem experiência em Lavadora</p>
<p><em>Tabelas</em></p>
<p><em>Query</em></p>
<pre><code class="language-sql">SELECT nome
FROM (tecnicos INNER JOIN experiencia
      ON tecnicos.num_tec = experiencia.num_tecnico)
WHERE experiencia.tipo = 'Lavadora';
</code></pre>
<p><em>Resultado</em><br>
<br>
</p>
<h4>Usando o <code>INNER JOIN</code> com 3 tabelas</h4>
<p><strong>Exemplo</strong>: Liste o nome dos técnicos e sua experiência em aparelhos da categoria 1</p>
<p><em>Tabelas</em><br>
<br>
</p>
<p><em>Query</em></p>
<pre><code class="language-sql">SELECT nome, anos_exp
FROM ((tecnicos INNER JOIN experiencia
       ON num_tec = num_tecnico) INNER JOIN Tipos
       ON tipo = tipo)
WHERE categoria = 1;
</code></pre>
<p><em>Resultado</em><br>
<br>
</p>
<h3><code>NATURAL JOIN</code></h3>
<p>Com ele você não precisa identificar quais colunas serão comparadas, pois ele fará a comparação entre <strong>campos com o mesmo nome</strong>.</p>
<p><strong>Sintaxe</strong></p>
<pre><code class="language-sql">SELECT coluna1, coluna2...
FROM tabela1 NATURAL JOIN tabela2;
</code></pre>
<p><em>Exemplo</em></p>
<pre><code class="language-sql">SELECT * FROM (tecnicos NATURAL JOIN experiencia);
</code></pre>
<p>Repare que não precisamos passar a condição de junção com <code>ON{:sql}</code>, já que ambas as tabelas possuem a coluna <code>tipo</code>.</p>
<p>O mesmo não da pra ser feito entre as tabelas <code>tecnicos</code> e <code>tipos</code>, pois <strong>não possuem</strong> colunas com o mesmo nome.</p>
<h3><code>OUTER JOIN</code></h3>
<p>O <code>OUTER JOIN{:sql}</code> é a variação de junção <strong>externa</strong>, e é composto por 3 tipos:</p>
<ul>
<li><code>LEFT OUTER JOIN{:sql}</code></li>
<li><code>RIGHT OUTER JOIN{:sql}</code></li>
<li><code>FULL OUTER JOIN{:sql}</code></li>
</ul>
<p>Diferente das junções <strong>internas</strong>, como o <code>INNER JOIN{:sql}</code>, as junções <strong>externas</strong> podem retornar valores mesmo quando não há conrrespondência entre as tabelas (valores <code>NULL{:sql}</code>).</p>
<h4><code>LEFT OUTER JOIN</code></h4>
<p>No <code>LEFT OUTER JOIN{:sql}</code> (ou simplesmente <code>LEFT JOIN{:sql}</code>), a prioridade é da tabela da <strong>esquerda</strong>, isto é, todos os registros da primeira tabela serão mostrados independente se houver correspondente nas outra tabela, após a equivalência das chaves usando o <code>ON{:sql}</code>.</p>
<p><strong>Sintaxe</strong></p>
<pre><code class="language-sql">SELECT coluna1, coluna2...
FROM tabela1 LEFT OUTER JOIN tabela2;
</code></pre>
<p><em>Exemplo</em></p>
<pre><code class="language-sql">SELECT * FROM (tecnicos LEFT OUTER JOIN experiencia);
</code></pre>
<h4><code>RIGHT OUTER JOIN</code></h4>
<p>No <code>RIGHT OUTER JOIN{:sql}</code> (ou simplesmente <code>RIGHT JOIN{:sql}</code>), a prioridade é da tabela da <strong>direita</strong>, isto é, todos os registros da segunda tabela serão mostrados independente se houver correspondente na outra tabela.</p>
<p>Pega todos os atributos da relação que está à direita, verifica se existe algum correspondente à esquerda, caso afirmativo, retorna os atributos da esquerda, e caso negativo, coloca o valor nulo nos atributos.</p>
<p><strong>Sintaxe</strong></p>
<pre><code class="language-sql">SELECT coluna1, coluna2...
FROM tabela1 RIGHT OUTER JOIN tabela2;
</code></pre>
<p><em>Exemplo</em></p>
<pre><code class="language-sql">SELECT * FROM (tecnicos RIGHT OUTER JOIN experiencia);
</code></pre>
<h4><code>FULL OUTER JOIN</code></h4>
<p>Faz o <code>RIGHT{:sql}</code> e o <code>LEFT{:sql}</code> ao mesmo tempo, ou seja, vai retornar dados que não tem em comum nas duas tabelas, e não só na tabela da direita ou da esquerda.</p>
<p><strong>Sintaxe</strong></p>
<pre><code class="language-sql">SELECT coluna1, coluna2...
FROM tabela1 FULL OUTER JOIN tabela2;
</code></pre>
<p><em>Exemplo</em></p>
<pre><code class="language-sql">SELECT * FROM (tecnicos FULL OUTER JOIN experiencia);
</code></pre>
<h2>Funções Matemáticas</h2>
<table>
<thead>
<tr>
<th>Função</th>
<th>Descrição</th>
<th>Exemplo</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>ABS(x){:sql}</code></td>
<td>Retorna o valor absoluto de <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">x</span></span></span></span></td>
<td><code>ABS(-5)</code> retorna <code>5</code></td>
</tr>
<tr>
<td><code>ROUND(x){:sql}</code></td>
<td>Retorna <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">x</span></span></span></span> arredondado</td>
<td><code>ROUND(5.5)</code> retorna <code>6</code></td>
</tr>
<tr>
<td><code>ROUND(x, d){:sql}</code></td>
<td>Retorna <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">x</span></span></span></span> arredondado para <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>d</mi></mrow><annotation encoding="application/x-tex">d</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">d</span></span></span></span> casas decimais</td>
<td><code>ROUND(5.3, 0)</code> retorna <code>5</code></td>
</tr>
<tr>
<td><code>CEIL(x){:sql}</code></td>
<td>Retorna o menor número inteiro maior ou igual a <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">x</span></span></span></span></td>
<td><code>CEIL(5.3)</code> retorna <code>6</code></td>
</tr>
<tr>
<td><code>FLOOR(x){:sql}</code></td>
<td>Retorna o maior número inteiro menor ou igual a <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">x</span></span></span></span></td>
<td><code>FLOOR(5.3)</code> retorna <code>5</code></td>
</tr>
<tr>
<td><code>FACTORIAL(x){:sql}</code></td>
<td>Retorna o fatorial de <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">x</span></span></span></span></td>
<td><code>FACTORIAL(5)</code> retorna <code>120</code></td>
</tr>
<tr>
<td><code>TRUNC(x, d){:sql}</code></td>
<td>Retorna <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">x</span></span></span></span> truncado para <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>d</mi></mrow><annotation encoding="application/x-tex">d</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">d</span></span></span></span> casas decimais</td>
<td><code>TRUNC(5.3, 0)</code> retorna <code>5</code></td>
</tr>
<tr>
<td><code>MOD(x, y){:sql}</code></td>
<td>Retorna o resto da divisão de <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">x</span></span></span></span> por <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi></mrow><annotation encoding="application/x-tex">y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span></span></td>
<td><code>MOD(5, 2)</code> retorna <code>1</code></td>
</tr>
<tr>
<td><code>PI(){:sql}</code></td>
<td>Retorna o valor de <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>π</mi></mrow><annotation encoding="application/x-tex">\pi</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span></span></span></span></td>
<td><code>PI()</code> retorna <code>3.141592653589793</code></td>
</tr>
<tr>
<td><code>LOG(x){:sql}</code></td>
<td>Retorna o logaritmo natural de <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">x</span></span></span></span></td>
<td><code>LOG(10)</code> retorna <code>2.302585092994046</code></td>
</tr>
<tr>
<td><code>RANDOM(){:sql}</code></td>
<td>Retorna um número aleatório entre 0 e 1</td>
<td><code>RANDOM()</code> retornar algo como <code>0.123456789</code></td>
</tr>
</tbody>
</table>
<h2>Funções de String</h2>
<table>
<thead>
<tr>
<th>Função</th>
<th>Descrição</th>
<th>Exemplo</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>CHARACTER_LENGTH(string){:sql}</code> ou <code>CHAR_LENGHT(string){:sql}</code></td>
<td>Retorna o número de caracteres em <code>string{:sql}</code></td>
<td><code>CHARACTER_LENGTH('Hello'){:sql}</code> retorna <code>5</code></td>
</tr>
<tr>
<td><code>LOWER(string){:sql}</code></td>
<td>Retorna <code>string</code> em minúsculo</td>
<td><code>LOWER('Hello'){:sql}</code> retorna <code>hello</code></td>
</tr>
<tr>
<td><code>UPPER(string){:sql}</code></td>
<td>Retorna <code>string</code> em maiúsculo</td>
<td><code>UPPER('Hello'){:sql}</code> retorna <code>HELLO</code></td>
</tr>
<tr>
<td><code>POSITION(substring IN string){:sql}</code></td>
<td>Retorna a posição da primeira ocorrência de <code>substring</code> em <code>string</code></td>
<td><code>POSITION('l' IN 'Hello'){:sql}</code> retorna <code>3</code></td>
</tr>
<tr>
<td><code>SUBSTRING(string FROM start FOR length){:sql}</code></td>
<td>Retorna uma parte de <code>string</code>, onde <code>start</code> determina a posicão do primeiro caractere e <code>length</code> determina quantos caracteres serão usados apartir de <code>start</code></td>
<td><code>SUBSTRING('Hello' FROM 2 FOR 3){:sql}</code> retorna <code>ell</code></td>
</tr>
<tr>
<td><code>CONCAT(string1, string2, ...){:sql}</code></td>
<td>Concatena <code>string1</code>, <code>string2</code> e outras <em>strings</em> posteriores</td>
<td><code>CONCAT('Hello', ' ', 'World'){:sql}</code> retorna <code>Hello World</code></td>
</tr>
</tbody>
</table>
<h2>Conversão de dados</h2>
<p>Existem alguns métodos para se converter um tipo de um dado em outro. O mais comum é utilizando a função <code>CAST{:sql}</code>, que converte um valor de um tipo de dado para outro.</p>
<p><strong>Sinatxe</strong></p>
<pre><code class="language-sql">CAST(valor AS tipo_de_dado);
</code></pre>
<p>Onde <code>valor</code> é o valor que será convertido e <code>tipo_de_dado</code> é o tipo para o qual o valor será convertido. Exemplo:</p>
<pre><code class="language-sql">CAST('5' AS NUMERIC);
</code></pre>
<p><em>Repare que no exemplo acima, <code>'5'</code> está como string por causa das aspas simples <code>'</code>, e queremos converter para um inteiro.</em></p>
<p>O mesmo pode ser feito utilizando a sintaxe <code>valor::tipo{:sql}</code>, onde <code>valor</code> é o valor que será convertido e <code>tipo</code> é o tipo para o qual o valor será convertido. Exemplo:</p>
<pre><code class="language-sql">5::TEXT;
</code></pre>
<p><em>Aqui, <code>5</code> está como inteiro, e estamos convertendo para o formato texto (string).</em></p>
<h3>Formato de dados</h3>
<pre><code class="language-txt">to_char ( timestamp, formato ) → texto
to_char ( timestamp com fuzo horário, formato ) → texto

to_char(timestamp '2002-04-20 17:31:12.66', 'HH12:MI:SS') → 05:31:12
</code></pre>
<pre><code class="language-txt">to_char ( intervalor, formato ) → texto

to_char(interval '15h 2m 12s', 'HH24:MI:SS') → 15:02:12
</code></pre>
<pre><code class="language-txt">to_char ( numeric_type, text ) → text

to_char(125, '999') → 125
to_char(125.8::real, '999D9') → 125.8
to_char(-125.8, '999D99S') → 125.80-
</code></pre>
<pre><code class="language-txt">to_char ( numeric_type, text ) → text

to_char(125, '999') → 125
to_char(125.8::real, '999D9') → 125.8
to_char(-125.8, '999D99S') → 125.80-
</code></pre>
<pre><code class="language-txt">to_date ( texto, data ) → data

to_date('05 Dec 2000', 'DD Mon YYYY') → 2000-12-05
</code></pre>
<pre><code class="language-txt">to_number ( texto, formato ) → numero

to_number('12,454.8-', '99G999D9S') → -12454.8
</code></pre>
<pre><code class="language-txt">to_timestamp ( texto, formato ) → timestamp com fuso horário

to_timestamp('05 Dec 2000', 'DD Mon YYYY') → 2000-12-05 00:00:00-05
</code></pre>
<section data-footnotes class="footnotes"><h2 class="sr-only" id="footnote-label">Footnotes</h2>
<ol>
<li id="user-content-fn-crud">
<p><strong>CRUD</strong> é a abreviatura de <strong>C</strong>reate, <strong>R</strong>ead, <strong>U</strong>pdate e <strong>D</strong>elete. É um acrônimo que se refere às quatro funções básicas de um sistema de banco de dados: Criar, Ler, Atualizar e Excluir. <a href="#user-content-fnref-crud" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
</li>
<li id="user-content-fn-dba">
<p><strong>DBA</strong> é a abreviatura de <em><strong>D</strong>ata<strong>b</strong>ase <strong>A</strong>dministrator</em> (Administrador de Banco de Dados.) <a href="#user-content-fnref-dba" data-footnote-backref="" aria-label="Back to reference 2" class="data-footnote-backref">↩</a></p>
</li>
<li id="user-content-fn-avg">
<p><em><strong>Average</strong></em> é a palavra em inglês para <strong>média</strong>. <a href="#user-content-fnref-avg" data-footnote-backref="" aria-label="Back to reference 3" class="data-footnote-backref">↩</a></p>
</li>
</ol>
</section>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>sql</category>
            <category>ddl</category>
            <category>dml</category>
            <category>dcl</category>
            <category>database</category>
            <category>fapam</category>
            <category>gti</category>
            <category>postgresql</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/sql-structured-query-language/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Mapeamento MER vs MR]]></title>
            <link>https://mateusf.com/blog/post/mapeamento-mer-vs-mr</link>
            <guid>mapeamento-mer-vs-mr</guid>
            <pubDate>Tue, 02 Apr 2024 13:33:59 GMT</pubDate>
            <description><![CDATA[Mapeamento e tradução do Modelo de Entidade-Relacionamento para o ModeloRelacional. Transcrição do conteúdo passado em aula no curso de GTI 1º período, na FAPAM,pelo professor Gabriel Ribeiro Diniz.]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/mapeamento-mer-vs-mr/thumbnail" alt=""> <br>
Esse artigo foi feito no intuito de servir como fixação dos conteúdos que estou estudando no momento, ministrado pelo professor <strong>Gabriel Ribeiro Diniz</strong> para as aulas de <strong>Banco de Dados</strong> no curso de <a href="https://www.fapam.edu.br/graduacao/project/gestao-de-t-i/"><strong>Gestão de TI - FAPAM</strong></a>.<br>
</p>
<h1>Introdução</h1>
<p>Em projetos de <strong>banco de dados</strong>, a modelagem de dados é feita através de um modelo de dados <strong>conceitual</strong>, geralmente o Modelo Entidade-Relacionamento (MER) que representa o esquema das visões e de toda a base de dados, especificados em diagramas ER.</p>
<p>O passo seguinte à modelagem dos dados é o mapeamento do diagrama da base de dados, obtido na fase anterior, para um modelo de dados <strong>lógico</strong>, o Modelo Relacional (MR), representado por meio de tabelas.</p>
<p>Para isso, considere o esquema ER mostrado a seguir, que será utilizado para ilustrar o procedimento de mapeamento. Este procedimento é apresentado passo-a-passo, a partir do exemplo do MER de uma <strong>empresa</strong>.</p>
<h1>Regras</h1>
<h2>Passo 1: Entidade</h2>
<p>Para cada entidade criar uma relação (Tabela) que inclua todos os atributos simples, para atributos compostos, inclua apenas os atributos simples que compõem o atributo composto. Escolha um dos atributos-chave da entidade para constituir a chave primária da relação (se a chave escolhida for composta, então o conjunto de atributos simples que a compõem irão formar a chave primária da relação).</p>
<p>No exemplo, foram criadas as relações EMPREGADO e PROJETO, correspondentes às entidades <strong><code>EMPREGADO</code></strong> e <strong><code>PROJETO</code></strong>, presentes no diagrama ER.</p>
<p>Os atributos indicados com chave-estrangeira (<code>*</code>) não foram incluídos ainda; eles serão adicionados durante os passo subsequentes.</p>
<p><strong>NOTAÇAO TEXTUAL</strong></p>
<p>EMPREGADO (EmpNome, DataNasc, CPF, Sexo, Rua, Cidade, Estado, Salário)<br>
PROJETO (ProjNome, ProjNúmero, ProjLocalização)</p>
<h2>Passo 2: Atributo multivalorado</h2>
<p>Para cada atributo multivalorado, criar uma nova relação que inclua o atributo simples como chave-primária. A relação também deve ter como atributo a chave-primária da relação que representa o atributo multivalorado. A chave-primária da relação será então a combinação das duas chaves.</p>
<p>No exemplo foi criado a relação LOCAL_DEPTO. O atributo "Localização" representa o atributo multivalorado <code>Localização</code> de <strong><code>DEPARTAMENTO</code></strong>, enquanto DeptoNúmero - como chave estrangeira - representa a chave-primária da relação DEPARTAMENTO. A chave primária de LOCAIS_DEPTO é a combinação de { DeptoNúmero, Localização }.</p>
<p><strong>NOTAÇAO TEXTUAL</strong></p>
<p>DEPARTAMENTO (DeptoNome, DeptoNúmero)<br>
<strong>LOCAL_DEPTO (DeptoNúmero*, Localização)</strong></p>
<h2>Passo 3: Entidade Fraca</h2>
<p>Para cada entidade fraca, criar uma relação e incluir todos os atributos simples (ou os componentes simples de atributos compostos) como atributos da relação. Além disso, incluir como chave-estrangeira a chave-primária da relação que corresponde ao tipo de entidade dependente. A chave-primária então é a combinação da chave da entidade "forte" e a chave parcial do tipo de entidade fraca.</p>
<p>No exemplo, foi criada a relação DEPENDENTE correspondente ao tipo de entidade fraca DEPENDENTE. Foi incluída a chave-primária da relação EMPREGADO como atributo de DEPENDENTE (chave estrangeira). A chave-primária da relação DEPENDENTE é a combinação { EmpCPF*, DependNome }, porque <strong>DependNome</strong> é a chave-parcial da entidade DEPENDENTE.</p>
<p><strong>NOTAÇAO TEXTUAL</strong></p>
<p>DEPENDENTE (EmpCPF*, DependNome, DependSexo, DepDTNasc, RelacaoParente)</p>
<h2>Passo 4: Relacionamento 1:1</h2>
<p>Para cada tipo de relacionamento 1:1 (um para um), a chave de uma das entidades participantes do relacionamento, vira atributo de outra entidade (como chave estrangeira da relação). Caso o relacionamento tenha atributo(s), este(s) também será(ão) incluídos como atributos na entidade escolhida.</p>
<p>Exemplo: foi mapeado o tipo de relacionamento 1:1 GERENCIA, escolhendo a entidade participante DEPARTAMENTO (<strong>porque sua participação no tipo de relacionamento GERENCIA é total, já que todo o departamento tem um gerente</strong>). Foi incluída a chave-primária da relação EMPREGADO como a chave-estrangeira na relação DEPARTAMENTO, chamada de EmpCPFGerente. Também foi incluído o atributo simples DataInício do tipo de relacionamento GERENCIA na relação DEPARTAMENTO, nomeado como DataInicioGerencia.</p>
<p>EMPREGADO (EmpNome, DataNasc, CPF, Sexo, Rua, Cidade, Estado, Salário)<br>
DEPARTAMENTO (DeptoNome, DeptoNúmero, <strong>EmpCPFGerente*, DataInicioGerencia</strong>)</p>
<h2>Passo 5: Relacionamento 1:N</h2>
<p>Para cada relacionamento 1:N (um para muitos), a chave da entidade participante do relacionamento com cardinalidade "1" vra atributo da entidade com cardinalidade "N". Isto é, incluir como chave-estrangeira da relação N, a chave-primária da relação 1 (isto porque cada instância da entidade do lado 1 está relacionada a mais de uma instância do lado N do relacionamento). Inclua também quaisquer atributos simples do tipo de relacionamento 1:N como atributos da entidade do lado "N".</p>
<p>Exemplo: Foram mapeados os tipos de relacionamento 1:N, CONTROLA, SUPERVISIONA e TRABALHA_PARA.<br>
Para CONTROLA incluiu-se a chave-primária da relação DEPARTAMENTO como a chave estrangeira na relação PROJETO, e foi chamado <strong>DeptoNum</strong>.<br>
Para SUPERVISIONA, incluiu-se a chave-primária da relação EMPREGADO como a chave-estrangeira na relação EMPREGADO, e foi denomido <strong>NumCPFSuper</strong>.<br>
No relacionamento TRABALHA-PARA, foi incluída a chave-primária da relação DEPARTAMENTO como a chave-estrangeira na relação EMPREGADO, e foi denominado <strong>DeptoNum</strong>.</p>
<p>DEPARTAMENTO (DeptoNome, DeptoNúmero, EmpCPFGerente, DataInicioGerencia)<br>
PROJETO (ProjNome, ProjNúmero, ProjLocalização, <strong>DeptoNum*</strong>)<br>
EMPREGADO (EmpNome, DataNasc, CPF, Sexo, Rua, Cidade, Estado, Salário, <strong>NumCPFSuper*</strong>)<br>
</p>
<p>EMPREGADO (EmpNome, DataNasc, CPF, Sexo, Rua, Cidade, Estado, Salário, NumCPFSuper*, <strong>DeptoNum*</strong>)<br>
DEPARTAMENTO (DeptoNome, DeptoNúmero, EmpCPFGerente, DataInicioGerencia)<br>
</p>
<h2>Passo 6: Relacionamento N:M</h2>
<p>Para cada tipo de relacionamento M:N (muitos para muitos), criar uma nova relação. Incluir como chave-estrangeira na nova relação as chaves-primárias das relações que representam os tipos de entidade participantes. As chaves-primárias será a combinação das chaves estrangeiras, neste caso. Inclua também qualquer atributo simples do tipo de relacionamento M:N (ou componentes simples dos atributos compostos) como atributo da nova relação. **Relacionamentos N:M sempre geram uma nova relação.</p>
<p>No exemplo foi mapeado o tipo de relacionamento M:N, TRABALHA_EM criando-se a relação TRABALHA_EM. Incluiu-se as chaves-primárias das relações PROJETO e EMPREGADO como chaves-estrangeiras na relação TRABALHA_EM, chamadas de <strong>ProjNúmero</strong> e <strong>EmpCPF</strong>. Também foi incluído o atributo NumHoras para representar o atributo horas do tipo de relacionamento.</p>
<p>A chave-primária da relação TRABALHA_EM é a combinação das chaves-estrangeiras { EmpCPF, ProjNúmero }.</p>
<p>EMPREGADO (EmpNome, DataNasc, CPF, Sexo, Rua, Cidade, Estado, Salário, NumCPFSuper*, DeptoNum*)<br>
PROJETO (ProjNome, ProjNúmero, ProjLocalização, DeptoNum*)<br>
<strong>TRABAHA_EM (EmpCPF*, ProjNúmero*, NumHoras)</strong><br>
</p>
<h2>Modelo Relacional (Resultado)</h2>
<p><strong>EMPREGADO</strong> (<em>EmpNome, DataNasc, CPF, Sexo, Rua, Cidade, Estado, Salário, NumCPFSuper*, DepNum*</em>)<br>
<strong>PROJETO</strong> (<em>ProjNome, ProjNumero, ProjLocalização, DeptoNum*</em>)<br>
<strong>TRABALHA_EM</strong> (<em>EmpCPF*, ProjNúmero*, NumHoras</em>)<br>
<strong>DEPARTAMENTO</strong> (<em>DeptoNome, DeptoNumero, EmpCPFGerente*, DataInicioGerencia</em>)<br>
<strong>DEPENDENTE</strong> (<em>DependNome, EmpCPF*, DependSexo, DependDataNasc, Relação</em>)<br>
<strong>LOCAL_DEPTO</strong> (<em>DeptoNumero*, Localização</em>)</p>
<h1>Especialização e Generalização</h1>
<p>Vamos agora levar em consideração uma generalização/especialização para converter do MER para MR.</p>
<p>Existem 3 formas de se converter um generalização/especialização de MER para MR:</p>
<ul>
<li>Criar uma única tabela para toda a hierarquia de generalização/especialização.</li>
<li>Criar uma tabela para a entidade genérica e uma tabela para cada entidade especializada.</li>
<li>Criar uma tabela para cada entidade especializada.</li>
</ul>
<h2>1 - Uma tabela para toda a hierarquia</h2>
<p>Você tem uma única tabela para todos os atributos iguais e específicos das entidades anteriores.</p>
<p>Quando tempos a especialização abaixo, podemos ter uma única tabela Cliente com todos os atributos possíveis.</p>
<h2>2 - Uma tabela para cada entidade</h2>
<p>Você tem a tabela genérica no exemplo acima, Pessoa, e as tabelas especializadas no exemplo Cliente e Funcionário.</p>
<p>As tabelas Funcionário e Cliente recebem uma chave estrangeira da tabela Pessoa.</p>
<p>Essa é uma das melhores formas (lembrar que, não se aplica a todos os cenários) de se modelar uma generalização/especialização, pois, ao invés de cadastrar todos iguais em diferentes tabelas, você cadastra na genérica, e apenas informa a FK na tabela especializada que o registro ficará.</p>
<p>Lembrando que nesta segunda maneira, você cadastra uma Pessoa e ela pode ser tanto cliente quanto funcionário, assim, evitando cadastrar as mesmas informações em duas tabelas diferentes.</p>
<h2>3 - Uma tabela para cada entidade especializada</h2>
<p>Você tem apenas as tabelas especializadas com os atributos repetidos</p>
<h1>Considerações</h1>
<p>O principal ponto a ser considerado em um esquema relacional, quando comparado ao esquema do MER, é que os tipos de relacionamento não são representados explicitamente, mas sim através de atributos incluídos em relações pela chave estrangeira.</p>
<p>O número final de relações nem sempre corresponde ao número de entidades do modelo ER, pois além de cada entidade (MER) constituir uma tabela (MR), atributos multivalorados e relacionamentos N:M também geram tabelas no MR.</p>
<p><strong>Sugestão</strong>: Siga as etapas na sequência sugerida para realizar o mapeamento. Em caso de dúvidas, volte às etapas anteriores.</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>mr</category>
            <category>mer</category>
            <category>fapam</category>
            <category>database</category>
            <category>definições</category>
            <category>gti</category>
            <category>modelo</category>
            <category>relacionamento</category>
            <category>entidade</category>
            <category>modelo-relacionaltabelas</category>
            <category>mapeamento</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/mapeamento-mer-vs-mr/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[MR - Modelo Relacional]]></title>
            <link>https://mateusf.com/blog/post/mr-modelo-relacional</link>
            <guid>mr-modelo-relacional</guid>
            <pubDate>Sun, 31 Mar 2024 21:39:53 GMT</pubDate>
            <description><![CDATA[Modelo Relacional (MR) para definição de relacionamentos de banco de dados. Transcrição do conteúdo passado em aula no curso de GTI 1º período, na FAPAM, pelo professor Gabriel Ribeiro Diniz.]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/mr-modelo-relacional/thumbnail" alt=""> <br>
Esse artigo foi feito no intuito de servir como fixação dos conteúdos que estou estudando no momento, ministrado pelo professor <strong>Gabriel Ribeiro Diniz</strong> para as aulas de <strong>Banco de Dados</strong> no curso de <a href="https://www.fapam.edu.br/graduacao/project/gestao-de-t-i/"><strong>Gestão de TI - FAPAM</strong></a>.<br>
</p>
<h1>Histórico</h1>
<p>O Modelo Relacional (MR) foi proposto por <strong>Edgar Frank Codd</strong> em meados da década de <strong>1970</strong>. Se trata de um conceito abstrato que define maneiras de: <strong>armazenar</strong>, <strong>manipular</strong> e <strong>recuperar dados</strong> estruturados.</p>
<p>Fortemente baseada na <a href="https://pt.wikipedia.org/wiki/Teoria_dos_conjuntos">teoria dos conjuntos</a>, oferecendo assim uma representaão simples e natural da informação.</p>
<p>O modelo relacional representa os dados em um banco de dados como uma <strong>coleção de tabela</strong> (relações). Cada tabela terá um <strong>nome</strong>, que será <strong>único</strong>, e um <strong>conjunto de atributos</strong> com seus respectivos nomes e domínios.</p>
<p>Esses astributos são as colunas da tabela, todos os valores da coluna são do mesmo tipo de dados.</p>
<h1>Conceitos</h1>
<p><strong>Relações (tabelas)</strong>: Os SGBDs relacionais representam os dados sob a forma de TABELAS bidimensionais (linhas x colunas), denominadas <strong>RELAÇÕES</strong>. É composto por 2 partes:</p>
<ul>
<li>Cabeçalho: <em>conjunto fixo de atributos</em></li>
<li>Corpo: <em>conjunto variável de tuplas (valor de atributo)</em></li>
</ul>
<p><strong>Tuplas</strong>: são as linhas da relação (tabela), representam uma instância da relação.</p>
<p><strong>Atributos</strong>: são as colunas ou campos da relação (tabela), representam as características da relação.</p>
<p><strong>Célula</strong>: A interseção de uma linha x coluna, ou seja, um valor de atributo. Cada célula de uma tabela contém um único valor, característica a qual designa-se por ATOMICIDADE (valor atômico).</p>
<p><strong>Domínio</strong>: Conjunto de valores atômicos, a partir do qual, um ou mais atributos extraem seus valores. Por exemplo: o domínio do atributo <code>idade</code> é um número inteiro entre 13 e 70, e o domínio do salário seria um número real entre 953,00 e 5300,00.</p>
<p>Domínio é um conceito semântico, exemplos:</p>
<ul>
<li>Peso, qte, valor - <em>São números reais (double, float)</em></li>
<li>Nome, Cidade - <em>São caracteres (string/varchar)</em></li>
<li>Data de nascimento - <em>São datas (date)</em></li>
</ul>
<p>Alguns domínios estão associados a um tipo de dados ou formato. Exemplo:</p>
<ul>
<li>CPF: <code>ddd.ddd.ddd-dd</code> onde <code>d</code> = <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">{</mo><mn>0</mn><mo separator="true">,</mo><mn>1</mn><mo separator="true">,</mo><mn>2</mn><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mn>9</mn><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">\{0, 1, 2, ...9\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">...9</span><span class="mclose">}</span></span></span></span> (inteiros)</li>
<li>Idade Empregado: inteiro entre 18 e 65 (<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>18</mn><mo>≤</mo><mi>i</mi><mi>d</mi><mi>a</mi><mi>d</mi><mi>e</mi><mo>≤</mo><mn>65</mn></mrow><annotation encoding="application/x-tex">18 \leq idade \leq 65</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7804em;vertical-align:-0.136em;"></span><span class="mord">18</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">≤</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8304em;vertical-align:-0.136em;"></span><span class="mord mathnormal">i</span><span class="mord mathnormal">d</span><span class="mord mathnormal">a</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">≤</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">65</span></span></span></span>)</li>
<li>Data: <code>dd/mm/aaaa</code></li>
</ul>
<h1>Descrição física e semântica</h1>
<p><strong>Descrição física</strong>: serve para identificar o tipo e o formato dos valores que compõem o domínio<br>
Ex.: <code>char(14)</code>, "(dd)ddddd-dddd".</p>
<p><strong>Descrição semântica</strong>: serve para ajudar na interpretação dos seus valores.<br>
Ex.: Números de telefones da FAPAM</p>
<h1>Chaves</h1>
<p>As tabelas relacionam-se umas comas outras atravez de <strong>chaves</strong>. Uma chave é um conjunto de um ou mais atributos que determinam a unicidade de cada registro. As chaves aparece sublinhadas.</p>
<p><strong>Chave candidata</strong>: Conjunto de atributos que definem unicamente e minimamente cada tupla em uma relação.<br>
Ex.: Empregado (Código, nome, CPF). Código e CPF são chaves candidatas.</p>
<p><strong>Chave Primária (Primary Key - PK)</strong>: É uma chave candidata escolhida para identificar unicamente cada tupla em uma relação. O valor deve ser único em cada linha (tupla) da relação.<br>
Ex.: Empregado (Código, nome, CPF). Código foi escolhido como a chave primária.</p>
<p><strong>Chave alternativa</strong>: São as chaves candidatas não escolhidas para chave primária.<br>
Ex.: Empregado (Código, nome, CPF). CPF é a chave alternativa.</p>
<p><strong>Chave estrangeira (Foreing Key - FK)</strong>: É um atributo de uma relação que constitui chave primária de uma outra relação. As chaves estrangeiras funciona como um elo de ligação entre relações (nas operações de consulta/acesso do bando de dados).</p>
<p>A chave estrangeira aparece com o símbolo aterísco após seu nome <code>*</code>.</p>
<p>Exemplo:</p>
<ul>
<li>Empregado (CodEmp, NomeEmp, CodDep*)</li>
<li>Departamento (CodDepto, NomeDep, CodGerente*)</li>
</ul>
<p>Na relação Empregado, CodEmp é a chave primária e CodDep é a chave estrangeira.<br>
Na relação Departamento, CodDepto é a chave primária e CodGerente é a chave estrangeira, pois o gerente deve estrar cadastrado na tabela Empregados, ou seja, <code>CodDep = CodDepto</code> e <code>CodGerente = CodEmp</code>.</p>
<p>Convenciona-se sublinhar os atributos que compõem a chave primária. Ex.: Empregado (Matrícula, Nome, Endereço, Função, Salário).</p>
<p>Um mesmo atributos pode ter nomes diferentes nas diversas relações em que participa. Exempo:</p>
<ul>
<li>Empregado (Matrícula, Nome, Endereço, Função, Salário, <em>NumDep</em>*).</li>
<li>Departamento (<em>CodDep</em>, Nome, Endereço).</li>
</ul>
<p>Atributos que representam diferentes conceitos podem ter o mesmo nome. Ex.: Ver os atributos <em>Nome</em> dos exemplos anteriores.<br>
</p>
<h1>Propriedades</h1>
<p>No modelo relacional, podem ser observadas as seguintes propriedades:</p>
<p>A - <strong>Uma tabela não deve possuir duas linhas iguais (tuplas duplicadas).</strong> Isso se explica pelo fato de que as linhas são componentes de um conjunto (a tabela) e se faz necessário poder distinguir os elementos de um conjunto. Assim, pelomenos um atributo componente da linha deve possuir um valor que a diferencie das demais.</p>
<p>B - <strong>Cada tabela ou relação deve possuir um nome prórprio, distinto das demais tabelas do mesmo banco de dados (similar às ENTIDADES, no MER).</strong> Ressalta-se que em banco de dados distintos duas tabelas podem ter o mesmo nome.</p>
<p>C - <strong>Cada atributo de uma mesma tabela deve possuir um nome diferente</strong> (valores de atributos são atômicos, sem repetição, ou seja, ocorrência de apenas um valor de atributo para cada célula da tabela). Por outro lado o mesmo atributo pode aparecer em outra tabela com o mesmo nome ou com nome diferente (sinônimo).</p>
<p>D - <strong>Toda tabela de um banco de dados deve possuir chave primária</strong></p>
<p>E - <strong>A ordem das linhas e colunas na tabela são inrrelevants (não altera o resultado)</strong></p>
<p>F - <strong>Os SGBD-R deve ser capazes de tratar, de maneira diferenciada, o valor NULO (NULL)</strong>, que indica a ausência de valor para um atributo em determinada linha. Nulo correspode na teoria de conjuntos, o conjunto vazio, e é diferente de zero ou branco. Os atributos podem ter diferentes nulos, sendo que nulo significa inexistência de valor.</p>
<h1>Restrições</h1>
<p>Condições restritivas do modelo relacional:</p>
<p>A - <strong>Restrição de integridade de chave</strong><br>
Toda tupla tem um atributo (ou uma combinação deles) que a identifica de maneira única na relação -> Chave Primária</p>
<p>B - <strong>Restrição de integridade de entidade</strong><br>
Nenhum valor da chave primária poderá ser nulo</p>
<p>C - <strong>Restrição de integridade referencial</strong></p>
<p>Não são permitidos valores de chave estrangeira em uma relação que não tenham sido cadastrados previamente como chave primária em outra relação.</p>
<p>Em outras palavras, estabelece que um conjunto de atributos de uma relação R1, é uma chave estrangeira se satisfaz as seguintes regras:</p>
<ul>
<li>Os atributos da chave estrangeira tem o mesmo domínio dos atributos da chave primária de outra relação R2.</li>
<li>Um valor da chave estrangeira numa tupla de R1 possui o mesmo valor da chave primária para alguma tupla em R2 ou é NULO.</li>
</ul>
<p>Exemplo: Empregado (matrícula, nome, salário, m_supervisor*).</p>
<h1>Operações de atualização em relações</h1>
<p>Considere as seguintes relações:</p>
<h2>Inserção</h2>
<p><strong>Inserção (<em>Insert</em>)</strong>: Inserir uma nova tupla na relação.</p>
<p><strong>O que fazer quando detectar uma violação de integridade?</strong></p>
<ul>
<li>Rejeitar a inserção</li>
<li>Tentar corrigir a anomalia para depois inserir</li>
</ul>
<h2>Exclusão</h2>
<p><strong>Exclusão (<em>Delete</em>)</strong>: Remover uma tupla da relação.</p>
<p><strong>O que fazer quando uma violação ocorrer numa remoção?</strong></p>
<ul>
<li>Rejeitar a remoção</li>
<li>Dar o efeito cascata na remoção, removendo todas as tuplas referenciadas por aquela tupla que está sendo removida.</li>
<li>Modificar os atributos referenciados para novos valores ou nulos (caso não façam parte da chave primária).</li>
</ul>
<h2>Atualização</h2>
<p><strong>Atualização (<em>Update</em>)</strong>: Alterar os dados em uma tupla da relação.</p>
<h1>Notações do modelo relacional</h1>
<h2>Notação tabular (tabelas)</h2>
<h2>Notação textual</h2>
<p>Empregado (Mat, Nome, Função, Salário, Dep*)<br>
Departamento (CodDep, Nome, MatrGerent*)</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>mr</category>
            <category>fapam</category>
            <category>database</category>
            <category>definições</category>
            <category>gti</category>
            <category>modelo</category>
            <category>relacionamento</category>
            <category>entidade</category>
            <category>modelo-relacional</category>
            <category>tabelas</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/mr-modelo-relacional/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[MER - Modelo de Entidade-Relacionamento #2]]></title>
            <link>https://mateusf.com/blog/post/mer-modelo-de-entidade-relacionamento-2</link>
            <guid>mer-modelo-de-entidade-relacionamento-2</guid>
            <pubDate>Fri, 29 Mar 2024 20:39:35 GMT</pubDate>
            <description><![CDATA[Introdução ao Modelo de Entidade-Relacionamento em banco de dados, parte 2. Transcrição do conteúdo passado em aula no curso de GTI 1º Período, na FAPAM, pelo professor Gabriel Ribeiro Diniz.]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/mer-modelo-de-entidade-relacionamento-2/thumbnail" alt=""> <br>
Esse artigo foi feito no intuito de servir como fixação dos conteúdos que estou estudando no momento, ministrado pelo professor <strong>Gabriel Ribeiro Diniz</strong> para as aulas de <strong>Banco de Dados</strong> no curso de <a href="https://www.fapam.edu.br/graduacao/project/gestao-de-t-i/"><strong>Gestão de TI - FAPAM</strong></a>.<br>
</p>
<h1>Generalização e Especialização</h1>
<p>Generalização e Especialização são técnicas de modelagem que permitem representar um conjunto de entidades de forma mais abstrata. Ocorre herança de atributos entre as entidades, isto é, as entidades de nível inferior herdam todos os atributos e relacionamentos da entidade a qual estão ligadas.</p>
<p><strong>SÍMBOLO:</strong> <em>Um <strong>triângulo</strong> de "cabeça para baixo"</em></p>
<p><br>
</p>
<h2>Especialização</h2>
<p>Usada quando um conjunto de entidades possui subgrupos com características próprias.</p>
<p>Especificação de subgrupos dentro de um conjunto de entidades que são distintas, isto é, possuem casacterísticas específicas em um vez que possuem atributos ou relacionamentos que não se aplica ao conjunto entidade de nível superior.</p>
<p><br>
</p>
<p><strong>Exemplo</strong> <strong><code>EMPREGADO</code></strong> pode ser <strong><code>HORISTA</code></strong> ou <strong><code>DIARÍSTA</code></strong>.</p>
<p><br>
</p>
<h2>Generalização</h2>
<p>Usada quando entidades distintas possuem características (atributos) em comum, possibilitando a criação de uma entidade mais genêrica que as represente.</p>
<p>Combina conjuntos de entidades, que compartilham as mesmas características (atributos/relacionamentos), em uma entidade de mais alto nível.</p>
<p><br>
</p>
<h2>Redundância</h2>
<p>A generalização/especialização é muito útil para evitar <strong>redundâncias</strong>, por exemplo:</p>
<p><br>
</p>
<p>Poderíamos refazer o modelo ER da seguinte forma:</p>
<p><br>
</p>
<h2>Conselhos práticos</h2>
<h3>ATRIBUTO vs GENEREALIZAÇÃO/ESPECIALIZAÇÃO</h3>
<p><strong>Questão</strong>: modelar um determinado objeto, por exemplo, a categoria funcional de cada empregado de uma empresa.</p>
<p>Como <strong>atributo</strong>?</p>
<ul>
<li>Categoria funcional como atributo da entidade <strong><code>EMPREGADO</code></strong>.</li>
</ul>
<p>Como <strong>generalização/especialização</strong>?</p>
<ul>
<li>Cada categoria funcional corresponderá a uma especialização da entidade <strong><code>EMPREGADO</code></strong>.</li>
</ul>
<p><br>
</p>
<h3>Atributo opcional</h3>
<p>Pode indicar subconjuntos de entidades que são modelados mais corretamente através de especializações. Exemplo:</p>
<p><br>
</p>
<h2>Tipos de generalização/especialização</h2>
<h3>Total</h3>
<p>Nesse tipo generalização/especialização, a existência da ocorrência da entidade genérica OBRIGATORIAMENTE implica na existência da ocorrência da entidade especializada.</p>
<h3>Parcial</h3>
<p>Nesse tipo de generalização/especialização, a existência da ocorrência da entidade genérica NÃO OBRIGA a existência da ocorrência da entidade especializada.</p>
<h3>Exclusiva</h3>
<p>Em uma hierarquia de generalização/especialização, uma ocorrência da entidade genérica é especializada no máximo uma vez, nas folhas da árvore de generalização/especialização.</p>
<h3>Compartilhada</h3>
<p>Em uma hierarquia de generalização/especialização, uma ocorrência da entidade genérica aparecer em várias entidades especializadas, nas folhas da árvore de generalização/especialização.</p>
<h3>União de tipos</h3>
<table>
<thead>
<tr>
<th> </th>
<th>Exclusiva</th>
<th>Compartilhada</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Total</strong></td>
<td><code>tx</code></td>
<td><code>tc</code></td>
</tr>
<tr>
<td><strong>Parcial</strong></td>
<td><code>px</code></td>
<td><code>pc</code></td>
</tr>
</tbody>
</table>
<p><strong>Total</strong> + <strong>Exclusiva</strong> (<code>tx</code>)</p>
<blockquote>
<p>Todo cliente DEVE ser ou pessoa física, ou pessoa jurídica, mas NÃO PODE ser ambos ao mesmo tempo.</p>
</blockquote>
<p><strong>Total</strong> + <strong>Compartilhada</strong> (<code>tc</code>)</p>
<blockquote>
<p>Toda nacionalidade DEVE ser ou braileira, ou indiana, ou japonesa, ou mais de uma ao mesmo tempo.</p>
</blockquote>
<p><strong>Parcial</strong> + <strong>Exclusiva</strong> (<code>px</code>)</p>
<blockquote>
<p>Todo Saiyajin PODE estar transformado OU NÂO, mas se estiver, so pode ter UMA transformação por vez.</p>
</blockquote>
<p><strong>Parcial</strong> + <strong>Compartilhada</strong> (<code>pc</code>)</p>
<blockquote>
<p>Um médico PODE ser um cardiologista/neurologista OU NÃO, e se for, pode ser MAIS DE UM, ao mesmo tempo.</p>
</blockquote>
<h2>Níveis de especialização</h2>
<p>Não existe um limite para o nível de especialização. A árvore de especialização pode ter mais de uma camada.</p>
<h2>Herança múltipla</h2>
<p>Uma herança múltipla ocorre quando uma entidade especializada é a especializada de mais de uma entidade genérica.</p>
<h1>Entidade associativa</h1>
<p>Suponhamos a seguinte situação: Considere o relacionamento abaixo, <strong><code>MÉDICO</code></strong>-<code>consulta</code>-<strong><code>PACIENTE</code></strong>, agora precisamos armazenar informações sobre medicamentos. Para isso vamos criar a entidade <strong><code>MEDICAMENTO</code></strong>.</p>
<p>Se associarmos a entidade <strong><code>MEDICAMENTO</code></strong> à entidade <strong><code>MÉDICO</code></strong>, só saberíamos qual médico receitou o medicamento, e não para qual paciente.</p>
<p>Se associarmos a entidade <strong><code>MEDICAMENTO</code></strong> à entidade <strong><code>PACIENTE</code></strong>, só saberíamos qual paciente recebeu a receita, e não quem receitou.</p>
<p>Queremos associar a entidade <strong><code>MEDICAMENTO</code></strong> à consulta. Porém, isso não está previsto no Modelo Entidade Relacionamento. Para isso foi criado o conceito de Entidade Associativa.</p>
<p>Esse conceito consiste em transformar um relacionamento em uma entidade para que dessa forma seja possível criar um relacionamento entre a entidade <strong><code>MEDICAMENTO</code></strong> e a entidade <strong><code>CONSULTA</code></strong>.</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>mer</category>
            <category>fapam</category>
            <category>database</category>
            <category>diagrama</category>
            <category>gti</category>
            <category>modelo</category>
            <category>entidade-relacionamento</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/mer-modelo-de-entidade-relacionamento-2/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Guia do Código Hacker]]></title>
            <link>https://mateusf.com/blog/post/guia-do-codigo-hacker</link>
            <guid>guia-do-codigo-hacker</guid>
            <pubDate>Sat, 09 Mar 2024 14:25:07 GMT</pubDate>
            <description><![CDATA[Guia e definições para criar um Código Hacker]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/guia-do-codigo-hacker/thumbnail" alt=""> <br>
Essa é uma tradução da publicação original <a href="http://files.catwell.info/misc/mirror/hackerkey.html">"The Hacker Key Guide"</a> de <a href="https://catwell.info/">Pierre 'catwell' Chapuis</a>.<br>
</p>
<h1>Sobre o Guia do Código Hacker</h1>
<p>O Guia do Código Hacker foi inspirado no excelente <a href="https://web.archive.org/web/20000511144513/http://www.geekcode.com/">Código Geek</a> (<em>Geek Code</em>) de Robert Hayden, que é um dos favoritos dos hackers há muito tempo. No entanto, o Código Geek não é atualizado há muito tempo e, embora a comercialização da Internet tenha eliminado grande parte do antigo ambiente hacker (MUDs, BBSes, DOS...), devemos tentar manter vivas as tradições hackers, por reimplementação, se necessário.</p>
<p>Vamos ver um exemplo de um bloco de Código Geek:</p>
<pre><code class="language-plaintext">-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d- s+: a- C++ US++++ P++ L+++ E--- W++ N+ o K- w--
O+ M+ V PS++ PE- Y PGP+ t+ 5 X R tv+ b+ DI+ D+
G++ e++ h--- r+++ y+
------END GEEK CODE BLOCK------
</code></pre>
<p>O Código Geek faz muitas coisas bem:</p>
<ul>
<li>É MUITO geek. Strings de texto curtas com delimitadores <code>+</code> ou <code>-</code> para mostrar posições relativas em um problema.</li>
<li>É único. É muito fácil identificar o código geek e ele vem sendo adotado por outros grupos que buscam formas de se identificar, mostrando sua versatilidade.</li>
<li>É muito simples determinar por quais coisas uma pessoa é apaixonada. No exemplo acima, uma rápida olhada mostra que a pessoa parece ser um geek casado, liberal e amante do Unix, que não liga muito para programas de TV.</li>
</ul>
<p>No entanto, também existem alguns problemas com o GeekCode:</p>
<ul>
<li>Em primeiro lugar, há muito espaço desperdiçado. Embora seja muito fácil determinar se uma pessoa é mestre em algo com 5 sinais de mais, é um desperdício. O local principal (e mais lógico) para exibir o código geek é no arquivo de assinatura. Ainda hoje, a netiqueta ainda favorece arquivos de assinatura curtos, e o Código Geek médio tem 6 linhas sozinho. Os geeks tendem a seguir a netiqueta quando possível, então isso faz com que as próprias pessoas visadas pelo Código Geek não o promovam em suas assinaturas!</li>
<li>O código foi projetado para se parecer com um bloco de chave PGP, mas inclui caracteres que não são válidos em uma chave PGP, em particular, o símbolo de menos <code>-</code> e parênteses <code>()</code> são muito comumente usados. Os caracteres válidos em uma chave PGP são [A-Za-z0-9], mais <code>+</code> e barra <code>/</code>. Também não há espaços em uma chave normal.</li>
<li>Não é enigmático o suficiente ;) Isso é uma brincadeira, mas é quase MUITO fácil determinar rapidamente o Código Geek de uma pessoa, o que meio que tira a diversão do tipo anel decodificador secreto das coisas.</li>
<li>O problema mencionado acima é que o Código Geek está desatualizado.</li>
</ul>
<p>O Guia do Código Hacker espera manter os aspectos bons do Código Geek e melhorar alguns dos ruins.<br>
Os objetivos de design do Guia do Código Hacker são:</p>
<ol>
<li>Uma chave normal com algumas opções de categoria extras deve caber em uma linha de texto de 80 colunas. Idealmente, ele deve ter espaço suficiente para que o URL da chave do hacker caiba na mesma linha, para dar às pessoas uma chance de descobrir o que diabos é.</li>
<li>Certifique-se de que os símbolos mais comumente usados também sejam símbolos de chave PGP válidos. Para compatibilidade com o Código Geek, usaremos mais símbolos que não são válidos, mas garantiremos que os mais usados sejam.</li>
<li>Mantenha o Guia atualizado. Só posso prometer que manterei o guia atualizado ou o entregarei a alguém que o faça. O tempo dirá se conseguirei cumprir essa promessa.</li>
</ol>
<h1>Formato de uma entrada de Código Hacker</h1>
<p>Uma Código Hacker é construído da seguinte forma:</p>
<ul>
<li>A categoria em questão será listada em letras minúsculas (por exemplo, u é para Unix).</li>
<li>O número correspondente à sua resposta à categoria (por exemplo, 7). Em vez de mais ou menos, é atribuída uma pontuação média de 5 para cada categoria. As respostas extremamente positivas são superiores a 5 (o máximo normal é 9), as respostas negativas são inferiores a 5 (o mínimo normal é 0).</li>
<li>As opções opcionais de gaiola devem estar no final e em letras maiúsculas (por exemplo, SL para Solaris, Linux).</li>
<li>Ao prosseguir para a próxima seção, não pule um espaço!</li>
</ul>
<p>Então, para nosso exemplo, a categoria Unix seria preenchida como: u7SL</p>
<h2>Modificadores (variáveis)</h2>
<p>As "variáveis" do Geek Code mais comumente usadas parecem ser "intervalos" (<code>@</code> e <code>()</code>) e "aspirante" (<code>></code>). Para seguir o Objetivo de Design nº 2, as seguintes alterações foram feitas na Chave Hackey:</p>
<ul>
<li><code>/</code> - Para indicar uma resposta de "intervalo", use a tecla barra (<code>/</code>) em sua resposta. Para a opção (<code>@</code>) de variação livre, use um <code>/</code> no final da sua resposta numérica, por exemplo. <code>u5/</code>. Para indicar um intervalo específico em sua resposta, use a barra entre suas duas respostas, por exemplo. você5/7.</li>
<li><code>+</code> - Para indicar sua classificação de "aspirante", use o símbolo de mais (<code>+</code>). Sim, parece estranho e (<code>></code>) é um caractere mais intuitivo, mas não usar um caractere-chave PGP válido quando é um dos dois únicos caracteres não alfanuméricos disponíveis seria uma farsa. Por exemplo, se você gosta de Unix, mas gostaria de ser um guru, você usaria u5+8.</li>
</ul>
<p>O restante dos símbolos são compatíveis com o Código Geek. Eles estão listados para compatibilidade com o Código Geek, embora sejam opcionais e sejam caracteres inválidos em uma chave PGP. Para completar, aqui estão eles:</p>
<ul>
<li><code>$</code> - Para indicar que você ganha a vida com um certo tipo de hacking de atividade relacionada, adicione um <code>$</code> no final, ex.: <code>u9$</code></li>
<li><code>?</code> - Afirma que não sabe nada sobre esta categoria. Se for esse o caso, por que você está criando um Código Hacker?</li>
<li><code>!</code> - Recusa veemente em participar da categoria. Isso normalmente deveria ser feito com um 0 para uma categoria, então realmente não deveria ser usado. Para ser consistente com o Código Geek, se você decidir usar este caractere, coloque-o SOMENTE no início de uma categoria e obviamente não insira um valor numérico.</li>
</ul>
<h1>O guia em sí</h1>
<p><code>v</code> - Versão - Inclua a versão atual como a primeira entrada em sua chave de hacker.</p>
<p>A versão atual do Hacker Key é v4.</p>
<h2>Parte I – Que tipo de hacker você é?</h2>
<p><code>sw</code> - <strong>Hacking de software</strong> (<em>Software Hacking</em>)</p>
<p><strong>9</strong> – Sou Bill Joy, Eric Raymond ou JWZ.<br>
<strong>8</strong> – Sou um uberhacker; Eu escrevi meu shell/depurador/editor/compilador em 30 linhas de código. Outras pessoas usam e amam meus hacks.<br>
<strong>7</strong> – Viva para Hackear, Hackeie para Viver!<br>
<strong>6</strong> – Não há nada melhor do que um hack elegante.<br>
<strong>5</strong> – Em média, fiz alguns hacks de software no meu dia.<br>
<strong>4</strong> – Já hackeei código uma ou duas vezes, software não é minha praia.<br>
<strong>3</strong> – Eu não hackeio software de jeito nenhum. Sou um programador estruturado!<br>
<strong>2</strong> – Não sou nem programador e muito menos hacker!<br>
<strong>1</strong> – Sou gerente e/ou trabalho na IBM.</p>
<p>Indique sua linguagem de hacking preferida</p>
<ul>
<li><code>C</code> C(++)</li>
<li><code>P</code> Perl</li>
<li><code>Y</code> Python</li>
<li><code>U</code> Unix Shell</li>
<li><code>B</code> (Visual) Basic</li>
<li><code>J</code> Java</li>
<li><code>A</code> Ada</li>
<li><code>S</code> Assembler</li>
<li><code>L</code> Lisp</li>
<li><code>G</code> Prolog</li>
<li><code>M</code> Esquema</li>
<li><code>F</code> Fortran</li>
<li><code>H</code> PHP</li>
<li><code>R</code> Rubi</li>
</ul>
<p><code>hw</code> - <strong>Hacking de hardware</strong> (<em>Hardware Hacking</em>)</p>
<p><strong>9</strong> – Eu sou Steve Wozniak.<br>
<strong>8</strong> – Tenho meu próprio gravador de eeprom no porão. Eu não vou usar o que não foi feito por mim mesmo.<br>
<strong>7</strong> – Meus projetos de hardware foram usados em produtos reais.<br>
<strong>6</strong> – Já brinquei com alguns desenhos de hardware, mas nunca fiz meu próprio hardware. Conheço o hardware do PC como a palma da minha mão.<br>
<strong>5</strong> – Construí todos os PCs da minha casa do zero. Newegg me conhece por meu primeiro nome.<br>
<strong>4</strong> – Eu construí um ou dois PCs na minha época. É apenas mais fácil prepará–los.<br>
<strong>3</strong> – As pessoas me perguntam o que significa USB, eu sei algumas coisas sobre hardware.<br>
<strong>2</strong> – Sei montar meu computador sem diagrama.<br>
<strong>1</strong> – Cara! Você tem um Dell!</p>
<p><code>ln</code> - <strong>Hacking de linguagem</strong> (<em>Language Hacking</em>)</p>
<p><strong>9</strong> – Eu sou J.R.R. Tolkien.<br>
<strong>8</strong> – Minha linguagem de estimação foi usada e estudada por outras pessoas.<br>
<strong>7</strong> – Pessoas que não me conhecem usaram palavras que criei. eu escrevi minha própria linguagem artificial.<br>
<strong>6</strong> – Sou conhecido por certas palavras ou frases, meus amigos usam minhas criações linguísticas regularmente.<br>
<strong>5</strong> – Criei uma frase ou inventei uma ou duas palavras novas.<br>
<strong>4</strong> – Sou um nazista gramatical; as pessoas odeiam falar comigo porque eu as corrijo no meio da frase.<br>
<strong>3</strong> – Odeio pessoas que não seguem as regras básicas do $LANG, que eu me esforcei para falar corretamente.<br>
<strong>2</strong> – Sou analfabeto e/ou só falo IM: l8r sk8r!<br>
<strong>1</strong> – Sou editor do Slashdot.</p>
<p><code>pr</code> - <strong>Programação</strong> <em>Ei, alguns hackers pensam que são programadores</em> ;-)</p>
<p><strong>9</strong> – Só programo em ADA, e ADORO!<br>
<strong>8</strong> – Atualmente estou programando um link de conectividade célebro–IDE.<br>
<strong>7</strong> – Eu programo bastante, e passo muito tempo no meu IDE de escolha.<br>
<strong>6</strong> – Definitivamente sou um programador, não um hacker. Eu gosto do básio, um editor de texto e um compilador/depurador.<br>
<strong>5</strong> – Sou um programador comum, prefiro pensar que sou um hacker.<br>
<strong>4</strong> – Sacrificarei o design elegante pelo desempenho ou tamanho.<br>
<strong>3</strong> – Comentários são para maricas! Se foi difícil escrever, deveria ser difícil de ler.<br>
<strong>2</strong> – Posso escrever olá mundo, mas meus programas não fazem tanto assim.<br>
<strong>1</strong> – Não consigo programar de jeito nenhum.</p>
<p>Indique sua metodologia de programação</p>
<ul>
<li><code>O</code> Orientado a Objetos</li>
<li><code>S</code> Estruturado</li>
<li><code>A</code> Orientado a Aspectos</li>
<li><code>U</code> Unificado</li>
<li><code>R</code> Racional Unificado</li>
<li><code>P</code> Processual</li>
<li><code>F</code> Funcional</li>
</ul>
<p><code>ck</code> - <strong>Cracking</strong> <em>O ato malicioso de invadir sistemas que obtém todos os destaques; o que pessoas não técnicas consideram "hacking".</em></p>
<p><strong>9</strong> – Trabalho para @Stake ou escrevo por 2600.<br>
<strong>8</strong> – Eu escrevo os "<em>sploits</em>" que todas as crianças usam. eu seria um <em>black–hat</em> profissional, exceto para esta economia.<br>
<strong>7</strong> – Black Hat – Cracking é coisa antiga para mim. Eu só comprometo um sistema se parece um desafio. <em>Script Kiddies</em> me adoram.<br>
<strong>6</strong> – Gray Hat – Algumas dos meus <em>cracks</em> são para o bem, outras são para o mal. Isto realmente depende de quem se beneficia com o que eu faço.<br>
<strong>5</strong> – Tento invadir sistemas ocasionalmente. É para fins de educação, é isso!<br>
<strong>4</strong> – White Hat – Eu estudo exploits porque sou eu quem tem que corrigir os sistemas quando eles são liberados. Eu assino o CERT.<br>
<strong>3</strong> – Já tentei uma ou duas vezes, mas achei errado. Eu fico com o warez.<br>
<strong>2</strong> – Nunca tento invadir um computador, isso é contra a lei!<br>
<strong>1</strong> – Mal sei quebrar um ovo!</p>
<p><code>ma</code> - <strong>Matemática</strong> <em>A matemática ocupa grande parte da computação, e portanto, o hacking. Indique o seu mais alto grau de Matématica.</em></p>
<p><strong>9</strong> – Cálculo/Teoria Avançada<br>
<strong>8</strong> – Equações Diferenciais<br>
<strong>7</strong> – Cálculo II<br>
<strong>6</strong> – Probabilidade/Estatísticas<br>
<strong>5</strong> – Álgebra Linear<br>
<strong>4</strong> – Cálculo I<br>
<strong>3</strong> – Terminei o HS Math e percebi que isso era o suficiente para mim<br>
<strong>2</strong> – Ainda no ensino médio e indo muito bem.<br>
<strong>1</strong> – Fico irritado com os números. Há muitos deles e outras coisas.</p>
<h2>Parte II – Guerra de S.O.!</h2>
<p><code>u</code> - <strong>Unix</strong></p>
<p><strong>9</strong> – Eu sou Ken Thompson.<br>
<strong>8</strong> – Eu sou um guru. Todo mundo me pede ajuda com suas máquinas Unix. Unix é mais que um sistema operacional, é minha religião!<br>
<strong>7</strong> – Utilizo exclusivamente Unix em todos os meus computadores. Se não é Unix, é uma merda!<br>
<strong>6</strong> – Gosto muito de Unix; Eu instalei o Linux uma ou duas vezes, mas principalmente uso Windows ou MacOS para minhas necessidades diárias.<br>
<strong>5</strong> – Unix está bem, é apenas uma ferramenta como qualquer outra.<br>
<strong>4</strong> – O Mac OS X é o mais próximo do Unix que eu gostaria de chegar.<br>
<strong>3</strong> – Não gosto de Unix, é muito enigmático, e que porcaria de <em>shell</em> é essa! A GUI é muito superior!<br>
<strong>2</strong> – Unix é uma abominação. É um daqueles sistemas operacionais mortos que não percebe ainda que está morto.<br>
<strong>1</strong> – Eu sou Bill Gates.</p>
<p>Insira seus sistemas operacionais *nix mais (menos) favoritos:</p>
<ul>
<li><code>L</code> Linux</li>
<li><code>I</code> Irix</li>
<li><code>A</code> AIX</li>
<li><code>S</code> (Open) Solaris</li>
<li><code>F</code> FreeBSD</li>
<li><code>N</code> NetBSD</li>
<li><code>O</code> OpenBSD</li>
<li><code>B</code> Outro BSD</li>
<li><code>H</code> HP-UX</li>
<li><code>M</code> MacOS X</li>
<li><code>T</code> Tru64</li>
</ul>
<p><code>w</code> - <strong>Windows</strong></p>
<p><strong>9</strong> – Eu trabalho para a Microsoft, eles me chamam de <em>code monkey</em>... bem, apenas <em>monkey</em>.<br>
<strong>8</strong> – Eu instalo todas as versões beta da versão mais recente do Windows que consigo sair da rede. Eu quero trabalhar na Microsoft.<br>
<strong>7</strong> – Desenvolvi meus próprios programas para Windows, VB e .NET me pertencem.<br>
<strong>6</strong> – Gosto muito do Windows; Eu tenho meu tema de área de trabalho e protetor de tela do jeitinho que eu gosto.<br>
<strong>5</strong> – O Windows está OK, estou bastante indiferente a isso.<br>
<strong>4</strong> – Quando é que vão parar de roubar ideias alheias e surgir com algo INOVADOR? Eu ainda o executo, o que mais há?<br>
<strong>3</strong> – Eu mantenho o Windows no meu disco rígido apenas para testar o novo hardware que compro. Regras do Linux!<br>
<strong>2</strong> – Aniquilei totalmente o Windows do meu disco sem olhar para trás!<br>
<strong>1</strong> – Na verdade, nunca usei o Windows, estou completamente imaculado!</p>
<ul>
<li><code>D</code> MS-DOS/Windows 3.x</li>
<li><code>N</code> Windows NT</li>
<li><code>T</code> Windows 2000</li>
<li><code>W</code> Windows 95/98/Me</li>
<li><code>C</code> Windows CE/Mobile</li>
<li><code>X</code> Windows XP</li>
<li><code>U</code> Windows Server 2003</li>
<li><code>V</code> Vista</li>
</ul>
<p>Modificadores especiais</p>
<ul>
<li><code>G</code> Utilizo máquinas Windows mas apenas com Cygwin instalado</li>
</ul>
<p><code>m</code> - <strong>MacOS (X)</strong> <em>Vamos ser sinceros, minhas crianças, o OS 9 está morto.</em></p>
<p><strong>9</strong> – Eu sou Steve Jobs.<br>
<strong>8</strong> – Já escrevi livros sobre programação com Cocoa e Carbon. Vejo você na WWDC!<br>
<strong>7</strong> – Adoro! O poder do Unix e uma GUI aqua elegante são o auge da computação. Eu escrevi um ou dois aplicativos ocasionais.<br>
<strong>6</strong> – Gosto do novo MacOS. Finalmente estabilidade E facilidade de uso!<br>
<strong>5</strong> – MacOS X está bem. Um bom front-end GUI para um sistema operacional Unix.<br>
<strong>4</strong> – Não gosto disso. Não há ênfase suficiente na CLI.<br>
<strong>3</strong> – Eu odeio isso. A GUI ocupa metade da minha RAM e ainda trava pra mim, mesmo sendo baseada em UNIX!<br>
<strong>2</strong> – Desprezo o MacOS X. Sinto falta do MacOS "Clássico" (&#x3C;= 9).<br>
<strong>1</strong> – Desprezo o MacOS X. Sinto falta do Apple II.</p>
<p><code>l</code> - <strong>Linux</strong> <em>O sistema operacional gratuito que mudou a computação. Para a turma do GNU/Software Livre, use <code>g/l</code> (GNU/Linux).</em></p>
<p><strong>9</strong> – Sou Linus Torvalds ou Alan Cox.<br>
<strong>8</strong> – Sou um hacker/mantenedor de pacotes ativos do kernel. Se o Linux não existir, talvez eu tenha que sair de casa de vez em quando!<br>
<strong>7</strong> – Sou um usuário avançado. Desenvolvi minha própria minidistribuição por capricho. Perdi a conta de quantos kernels compilei.<br>
<strong>6</strong> – Gosto muito de Linux. Eu tentei algumas distribuições e estou quase decidindo por uma. <em>Windows sucks</em>.<br>
<strong>5</strong> – Linux é ok.<br>
<strong>4</strong> – Não gosto de Linux. Ainda depende muito da linha de comando.<br>
<strong>3</strong> – Eu odeio Linux. Não é realmente UNIX, é uma cópia barata. Essa coisa toda de feridas abertas nunca vai funcionar!<br>
<strong>2</strong> – Eu desprezo o Linux e seus apoiadores comunistas. Graças a Deus há um uma grande empresa como a Microsoft e um ótimo sistema operacional como o Windows!<br>
<strong>1</strong> – Trabalho para a SCO</p>
<p>Inclua sua distribuição favorita. Como qualquer bom fanático sabe, só pode haver um!</p>
<ul>
<li><code>A</code> Damn Small</li>
<li><code>D</code> Debian</li>
<li><code>E</code> (Open) SuSE</li>
<li><code>F</code> Fedora Core</li>
<li><code>G</code> Gentoo</li>
<li><code>I</code> (Lin|Free) spire</li>
<li><code>K</code> Knoppix (et al)</li>
<li><code>L</code> Linux From Scratch</li>
<li><code>M</code> Mandriva</li>
<li><code>P</code> Puppy</li>
<li><code>R</code> Red Hat</li>
<li><code>S</code> Slackware</li>
<li><code>U</code> Ubuntu (et al)</li>
<li><code>V</code> Vetor</li>
</ul>
<p><code>O</code> – outra distro de sua escolha! Existem mais distros do que letras, e eles vêm, vão e se fundem mais rápido do que posso atualizar. Então, aqui está a sintaxe para adicionar seu favorito:<br>
Adicione o nome da sua distribuição imediatamente após o <code>O</code> e acrescente um caractere de barra (<code>/</code>), exemplo:<br>
<code>lOgNewSense/</code> para os entusiastas do combo FSF-and-Ubuntu. O modificador <code>O</code> deve ser o ÚLTIMO listado para esta categoria para minimizar confusão.</p>
<p><code>i</code> - <strong>IDE/Editor de texto</strong></p>
<p>Como todos parecem ter seu próprio editor de texto favorito, os números mostrarão seu interesse em IDE/integração, bem como seu ambiente favorito.</p>
<p><strong>0</strong> – cat<br>
<strong>1</strong> – ed<br>
<strong>2</strong> – vi (e seus clones)<br>
<strong>3</strong> – jed<br>
<strong>4</strong> – jove<br>
<strong>5</strong> – pico/nano<br>
<strong>6</strong> – emacs<br>
<strong>7</strong> – CodeWarrior<br>
<strong>8</strong> – Visual Studio<br>
<strong>9</strong> – Xcode<br>
<strong>A</strong> – Anjuta<br>
<strong>C</strong> – Eclipse<br>
<strong>D</strong> – Delphi<br>
<strong>E</strong> – ee<br>
<strong>F</strong> – (v)FTE<br>
<strong>G</strong> – GNUstep<br>
<strong>H</strong> – HTE<br>
<strong>I</strong> – NEdit<br>
<strong>J</strong> – jEdit<br>
<strong>L</strong> – Idle<br>
<strong>N</strong> – Notepad <em><del>doente</del></em><br>
<strong>P</strong> – Powerbuilder<br>
<strong>T</strong> – Textpad<br>
<strong>O</strong> – outro IDE de sua escolha! Sim, quase ficamos sem cartas para IDEs, então aqui está a sintaxe para adicionar seu editor ou IDE favorito:<br>
Adicione seu programa imediatamente após o <code>O</code> e acrescente um caractere de barra (<code>/</code>), por exemplo: <code>iOBBEdit/</code> para os fãs do BBEdit por aí, ou <code>iOdd/</code> para aqueles verdadeiros durões do Unix (não). O modificador <code>O</code> deve ser o ÚLTIMO listado para esta categoria para minimizar confusão.</p>
<h2>Parte III – Vida e Estilo de Vida - seção "work friendly"</h2>
<p><code>e</code> - <strong>Educação</strong> <em>Indique o seu nível de escolaridade mais alto.</em></p>
<p><strong>9</strong> – Sou onisciente, seu idiota insensível!<br>
<strong>8</strong> – Doutorado<br>
<strong>7</strong> – Mestrado<br>
<strong>6</strong> – Bacharelado<br>
<strong>5</strong> – Escola Comercial/Técnica/Associados<br>
<strong>4</strong> – Alguma faculdade<br>
<strong>3</strong> – Diploma de ensino médio<br>
<strong>2</strong> – Atualmente cursando o ensino médio<br>
<strong>1</strong> – Ensino fundamental/médio<br>
<strong>0</strong> – Não precisamos de educação</p>
<p><code>t</code> - <strong>Televisão</strong> <em>A maioria dos hackers não assiste muita TV (é hora de eles estarem hackeando!), mas para completar, ela está incluída.</em></p>
<p><strong>9</strong> – Sou Max Headroom.<br>
<strong>8</strong> – Faz tempo que desisti de outras coisas como trabalhar, conversar com outras pessoas e sair de casa. Tenho soro intravenoso e diálise, então não preciso me preocupar com funções corporais incômodas.<br>
<strong>7</strong> – Assisto TV religiosamente. A televisão nunca está desligada na minha casa. Tenho um gerador para poder assistir TV mesmo quando há queda de energia!<br>
<strong>6</strong> – Assisto muita TV. Eu tenho um TiVo só para poder assistir todos os programas das minhas séries favoritas!<br>
<strong>5</strong> – Assisto TV algumas horas por dia e tenho alguns programas favoritos.<br>
<strong>4</strong> – Assisto TV de vez em quando. Simplesmente não há mais muita coisa boa.<br>
<strong>3</strong> – TV é um lixo. Prefiro ler um livro ou dar um passeio.<br>
<strong>2</strong> – A TV é apenas a ferramenta de controle do (Diabo | Governo | Grandes Empresas)! Jogue fora sua TV!<br>
<strong>1</strong> – Eu sou Amish</p>
<p>Série de TV Hackers:</p>
<ul>
<li><code>T</code> Star Trek</li>
<li><code>N</code> TNG</li>
<li><code>D</code> DS9</li>
<li><code>V</code> Voyager</li>
<li><code>E</code> Enterprise</li>
<li><code>B</code> Babylon 5</li>
<li><code>S</code> Stargate SG1/Atlantis</li>
<li><code>H</code> Xena/Hércules</li>
<li><code>L</code> LEXXX</li>
<li><code>F</code> Farscape</li>
<li><code>R</code> Red Dwarf</li>
<li><code>X</code> The X Files</li>
<li><code>M</code> Monty Python</li>
<li><code>A</code> Adult Swim</li>
<li><code>G</code> Battlestar Galactica</li>
<li><code>W</code> Doctor Who</li>
</ul>
<p><code>b</code> - Livros (<em>Books</em>) _Muita variedade aqui, já que alguns hackers são ávidos leitores, enquanto outros se limitam à web.</p>
<p><strong>9</strong> – Sou obcecado por leitura. Na verdade, escrevo meus próprios contos/poesias, além de ler livros.<br>
<strong>8</strong> – Sou uma espécie de leitor ávido, procuro ler um livro por semana/mês.<br>
<strong>7</strong> – Leio livros reais, não apenas referências técnicas.<br>
<strong>6</strong> – Pego o livro ímpar. Conheço bem as fronteiras locais.<br>
<strong>5</strong> – Leio livros ocasionalmente. Você quer dizer além dos livros da O'Reilly? Ah, então não.<br>
<strong>4</strong> – Não leio livros, a web é um meio de leitura suficiente para mim.<br>
<strong>3</strong> – Não leio um livro desde a faculdade.<br>
<strong>2</strong> – Não leio um livro desde o ensino médio.<br>
<strong>1</strong> – Sou analfabeto (Ver ln1).</p>
<p>Livros e autores favoritos dos hackers:</p>
<ul>
<li><code>A</code> Isaac Asimov</li>
<li><code>D</code> O Novo Dicionário do Hacker</li>
<li><code>G</code> William Gibson</li>
<li><code>H</code> Guia do Mochileiro</li>
<li><code>I</code> Trilogia Illuminatus</li>
<li><code>L</code> C. S. Lewis</li>
<li><code>K</code> Philip K. Dick</li>
<li><code>M</code> Páginas de Manual/Texto informativo</li>
<li><code>O</code> Livros técnicos O'rielly</li>
<li><code>P</code> Série Harry Potter</li>
<li><code>R</code> <em>Request for Comments</em> (RFCs)</li>
<li><code>S</code> Neil Stephenson</li>
<li><code>T</code> J.R.R. Tolkien</li>
</ul>
<p><code>en</code> - <strong>Criptografia</strong> <em>O único obstáculo real entre seus dados e um cracker, ou não?</em></p>
<p><strong>9</strong> – Tenho meu próprio algoritmo de criptografia com meu nome.<br>
<strong>8</strong> – Posso decifrar a Enigma na minha cabeça.<br>
<strong>7</strong> – Eu uso GnuPG para todos os emails e tenho muitos sistemas de arquivos criptográficos no meu disco rígido. Se você quiser meus dados, terá que conquistá-los!<br>
<strong>6</strong> – Utilizo criptografia com frequência. Quer assinar minha chave?<br>
<strong>5</strong> – Gosto e uso criptografia.<br>
<strong>4</strong> – Não uso criptografia. Não tenho nada a esconder.<br>
<strong>3</strong> – A criptografia é uma sobrecarga desnecessária. Se você usá-lo, deve ter algo a esconder!<br>
<strong>2</strong> – Somente terroristas usam criptografia. O governo deveria ter <em>back doors</em> para todos os mecanismos de criptografia.<br>
<strong>1</strong> – Somente o governo deveria poder usar criptografia para poder manter seus segredos seguros!</p>
<p><code>g</code> - <strong>Jogos</strong> <em>Seja console ou PC, os videogames são populares entre alguns hackers.</em></p>
<p><strong>9</strong> – Eu sou John Carmack.<br>
<strong>8</strong> – Desenvolvi o jogo ocasional. As pessoas me consideram um guru dos jogos. As pessoas se desconectam dos servidores quando me veem fazer logon.<br>
<strong>7</strong> – Brinco o tempo todo, quando não estou hackeando, comendo ou dormindo.<br>
<strong>6</strong> – Jogo com frequência, tenho um ou dois consoles e/ou alguns jogos para PC.<br>
<strong>5</strong> – Vou pegar um jogo ocasional.<br>
<strong>4</strong> – Eu costumava jogar videogame na época dos 8 bits, mas não mais.<br>
<strong>3</strong> – Não gosto de videogame, nessa hora eu poderia estar hackeando.<br>
<strong>2</strong> – Não gosto de videogame, nessa hora eu poderia estar dormindo.<br>
<strong>1</strong> – Sou péssimo em videogame.</p>
<p>Gênero:</p>
<ul>
<li><code>R</code> RPG Gráfico</li>
<li><code>A</code> Ação/Aventura</li>
<li><code>S</code> Esportes</li>
<li><code>Z</code> Puzzle</li>
<li><code>T</code> Baseado em texto/MUD</li>
<li><code>O</code> Tiro</li>
<li><code>V</code> Jogos multijogador massivo (<em>como você encontra tempo para hackear??</em>)</li>
<li><code>G</code> Estratégia em tempo real</li>
</ul>
<p>Console:</p>
<ul>
<li><code>C</code> Sistemas "clássicos" (<em>ou seja, mortos</em>) - Nintendo [S]NES, Sega</li>
<li><code>M</code> Sistemas modernos (PS2/3, XBOX (360), GameCube/Wii).</li>
<li><code>H</code> Portáteis (Gameboy/PSP)</li>
<li><code>P</code> PC Gamer</li>
</ul>
<h2>Parte IV – Vida e Estilo de Vida - seção "work unfriendly"</h2>
<p>Sim, pessoas que trabalham em megacorporações malignas foram punidas por terem essas seções em seus Códigos Hacker, então moveremos esta seção para o final. Observe que TODAS as seções são OPCIONAIS, mas esta em particular você pode querer deixar de fora.</p>
<p><code>a</code> - <strong>Idade</strong></p>
<p><strong>[0-9][0-9]</strong> – Idade real<br>
<strong>[0-9]X</strong> – Só tenho vontade de atualizar minha idade uma vez por década!<br>
<strong>F</strong> – 100+ (Velho Peido)<br>
<strong>Eu</strong> – Imortal<br>
<strong>N</strong> – N/A ou Não é da sua conta</p>
<p><code>s</code> - <strong>Sexo</strong> <em>Se não tivéssemos, de onde viriam os bebês?</em></p>
<p><strong>9</strong> – Meu nome é Jenna Jameson.<br>
<strong>8</strong> – Sou um (a) ninfomaníaco (a). Se não faço sexo a cada 6 horas fico totalmente irritado.<br>
<strong>7</strong> – Já fiz mais do que a minha cota de sexo. Eu sou um garanhão!<br>
<strong>6</strong> – Já fiz sexo mais do que algumas vezes. Ainda estamos no cenário do namoro, então não vamos entrar em números.<br>
<strong>5</strong> – Já fiz sexo. Próximo assunto.<br>
<strong>4</strong> – Não fiz sexo, não que não tenha tido oportunidade mas estou me salvando.<br>
<strong>3</strong> – Ainda nem passei da segunda base. Assim que meu rosto melhorar, vou pegar alguns!<br>
<strong>2</strong> – Sexo é sujo! Guarde para alguém que você ama!<br>
<strong>1</strong> – Sou membro do clero. Nada para mim, obrigado.</p>
<p><strong>0</strong> – Sou um eunuco.<br>
<strong>$</strong> – Sou uma prostituta.</p>
<ul>
<li><code>M</code> Masculino</li>
<li><code>G</code> Gay/Lésbica</li>
<li><code>S</code> Solteiro</li>
<li><code>T</code> Travesti</li>
<li><code>F</code> Feminino</li>
<li><code>B</code> Bissexual</li>
<li><code>R</code> Casada</li>
<li><code>D</code> BDSM</li>
<li><code>W</code> Swinger</li>
<li><code>I</code> Envolvido (namoro)</li>
</ul>
<p><code>r</code> - <strong>Religião</strong> <em>Geralmente os hackers acreditam em alguma coisa, mesmo que seja apenas em seu sistema operacional favorito. Outros têm uma opinião real sobre um Poder Superior</em></p>
<p><strong>9</strong> – Eu sou Deus, seu tolo mortal!<br>
<strong>8</strong> – Panteísta – O Universo É Deus.<br>
<strong>7</strong> – Pagão/Wiccano – Eu adoro mais a natureza do que uma divindade.<br>
<strong>6</strong> – Politeísta – Acredito em múltiplos Deuses.<br>
<strong>5</strong> – Monothiest – Só existe um Deus.<br>
<strong>4</strong> – Teísta – Deus existe e interage com o mundo e com Seus seguidores.<br>
<strong>3</strong> – Deísta – Deus existe, mas não intervém no mundo.<br>
<strong>2</strong> – Agnóstico – Inseguro da existência de Deus.<br>
<strong>1</strong> – Ateu – Deus não existe.</p>
<p><code>p</code> - <strong>Política</strong></p>
<p>Para a versão 4, use as classificações do Political Compass (<a href="http://www.politicalcompass.org">www.politicalcompass.org</a>). Basta listar seu nível econômico "Esquerda/Direita" e o nível social "Libertário/Autoritário" com uma barra entre elas, ou arredonde para cima/para baixo para o número inteiro mais próximo para economizar espaço (preferencial). Sim, o símbolo (<code>-</code>) não é PGP válido, mas pelo menos a categoria agora é um tanto útil.</p>
<p><img src="assets/political-compass.png" alt="Compasso político exemplo"></p>
<p>Se você listar apenas um número nesta categoria, será consideradoa a classificação Social Libertário/Autoritário, já que as questões sociais tendem a ser mais importantes para os hackers.</p>
<p>Exemplo (ambas as categorias): <code>p-4,20/-5,10</code> ou (preferencialmente) <code>p-4/-5</code><br>
Exemplo (somente social): <code>p6.10</code> ou (preferencialmente) <code>p6</code></p>
<h1>Exibindo seu Código Hacker</h1>
<p>Devido ao seu design, o Código Hacker deve caber discretamente em seu arquivo de assinatura. Como o Guia do Código Hacker não é muito conhecido, se você puder incluir uma referência ao site, isso ajudará a divulgar o Guia. Aqui está um exemplo da versão 4 do Código Hacker:</p>
<pre><code class="language-plaintext">v4sw5Uhw6ln5pr7FOck5ma4u7Lw3Vm5l6OManjaro/i2OVscode/e6t5b7ATen6g5RASOCMPaNr2p1/-9 hackerkey.com
</code></pre>
<h1>Quem é responsável pelo Código Hacker?</h1>
<p>O crédito deve ficar com você, <em>Chris Allegretta</em> &#x3C;<a href="mailto:chrisa@asty.org">chrisa@asty.org</a>>. Inspiração adicional, sugestões e feedback foram dados por <em>Murray Schwalbaum</em>, &#x3C;<a href="mailto:loser@e0f.org">loser@e0f.org</a>>. Obrigado também a <em>Charles Mason</em>, <em>Jim Ault</em>, <em>Eric Tucker</em> e <em>Jason Burks</em> pelas sugestões para a <strong>versão 0</strong>.</p>
<p>Para a <strong>versão 2</strong>, gostaria de agradecer: <em>Daniel Keep</em>, <em>Luke-Jr</em>, <em>Tony Lainson</em> e <em>Cody Hatch</em> pela revisão da seção Política.</p>
<p>Para a <strong>versão 3</strong>, gostaria de agradecer a <em>Jon Spriggs</em>, <em>Stephen E. Mynhier</em>, <em>Kyle Goetz</em>, <em>Neil Williams</em>, <em>Roie Marianer</em>, <em>Eric Davis</em> e <em>Joey Harrison</em> pelas sugestões de categoria ou organização.</p>
<p>Para a <strong>versão 4</strong>, gostaria de agradecer a <em>Scott A Gallaher</em> (<code>w</code>), <em>Thomas Jollans</em> (<code>ma</code> e <code>e</code>), <em>Jon Wickes</em> (<code>g</code>), <em>Matej Cizek</em> e <em>Fabio Emilio Costa</em> (<code>b</code>), <em>Sandy Knight</em> por <code>O</code> em (<code>l</code>) e (<code>i</code>), e especialmente a <em>Carlos Alberto Pinto Peixoto Bastos Santos</em> pelas diversas sugestões para (<code>l</code>) e por me indicar o site do Political Compass para (<code>p</code>).</p>
<h1>Feedback - Por favor!</h1>
<p>O Guia ainda é bem jovem e estou muito interessado em ouvir a opinião de vocês sobre o que você gosta, o que não gosta e acha que o Guia precisa ou não. Por favor, não sugira mudanças radicais na própria estrutura do código, pois esta é a única área com a qual me sinto bastante confortável. Envie suas idéias para <a href="mailto:chrisa@asty.org">chrisa@asty.org</a>.</p>
<h1>Licença</h1>
<blockquote>
<p>Direitos autorais <strong>(c) 2003-2006 Chris Allegretta</strong><br>
É concedida permissão para copiar, distribuir e/ou modificar este documento sob os termos da GNU Free Documentation License, Versão 1.2 ou qualquer versão posterior publicada pela Free Software Foundation; sem seções invariantes, sem textos de capa e sem textos de contracapa. Uma cópia da licença está incluída na seção intitulada "GNU Free Documentation License".</p>
</blockquote>
<h1>Histórico</h1>
<ul>
<li><code>v0</code> - Lançado em <strong>29.11.2003</strong> - lançamento RFC</li>
<li><code>v1</code> - Lançado em <strong>08.02.2004</strong> - Adicionadas seções de Programação e Matemática, adicionada categoria Swinger a Sexo, categorias de jogos renovadas</li>
<li><code>v2</code> - Lançado em <strong>17.04.2005</strong> - Divida a seção III em 'amigável ao trabalho' e 'hostil ao trabalho'. Reescreveu a categoria política por ser muito centrada na política dos EUA.</li>
<li><code>v3</code> - Lançado em <strong>22.02.2006</strong> - Adicionado: PHP e Ruby para <code>sw</code>, Dr Who e Battlestar Galactica para <code>t</code>, Idle e Anjuta para <code>i</code>, Envolvido para <code>s</code>, Windows Server 2003 e Vista para <code>w</code>. Alterado: duplicar <code>S</code> para atiradores para <code>O</code> em <code>g</code>.</li>
<li><code>v4</code> - Lançado em <strong>29.12.2006</strong> - Adicionado: Cygwin para <code>w</code>, MMO e RTS para <code>g</code>, muitas novas entradas para <code>b</code>. Alterado: <code>m</code> e <code>e</code> retrabalhados para os hackers ainda na escola secundária, <code>l</code> completamente renovado (várias letras de distro alteradas e adicionadas) e adicionadas (<code>O</code>) outras categorias especificadas pelo usuário a <code>l</code> e <code>i</code>, descartadas categorias <code>p</code> em favor das classificações do site Polical Compass.</li>
</ul>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>hacker</category>
            <category>geek</category>
            <category>tradução</category>
            <category>cyberpunk</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/guia-do-codigo-hacker/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[MER - Modelo de Entidade-Relacionamento #1]]></title>
            <link>https://mateusf.com/blog/post/mer-modelo-de-entidade-relacionamento-1</link>
            <guid>mer-modelo-de-entidade-relacionamento-1</guid>
            <pubDate>Wed, 06 Mar 2024 14:12:19 GMT</pubDate>
            <description><![CDATA[Introdução ao Modelo de Entidade-Relacionamento em banco de dados, parte 1. Transcrição do conteúdo passado em aula no curso de GTI 1º Período, na FAPAM, pelo professor Gabriel Ribeiro Diniz.]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/mer-modelo-de-entidade-relacionamento-1/thumbnail" alt=""> <br>
Esse artigo foi feito no intuito de servir como fixação dos conteúdos que estou estudando no momento, ministrado pelo professor <strong>Gabriel Ribeiro Diniz</strong> para as aulas de <strong>Banco de Dados</strong> no curso de <a href="https://www.fapam.edu.br/graduacao/project/gestao-de-t-i/"><strong>Gestão de TI - FAPAM</strong></a>.<br>
</p>
<h1>Introdução</h1>
<p><strong>MER</strong> - <strong>M</strong>odelo <strong>E</strong>ntidade-<strong>R</strong>elacionamento</p>
<blockquote>
<p>Baseia-se na percepção de um universo constituído por um grupo básico de objetos chamados <strong>entidades</strong> e por <strong>relacionamentos</strong> entre estes objetos.<br>
- Peter Chen, 1976</p>
</blockquote>
<p>O MER é um modelo de dados conceitual de alto-nível, ou seja, seus conceitos foram projetados para serem compreensíveis a usuários, descartando detalhes de como os dados são armazenados.</p>
<h2>Vantagens</h2>
<ul>
<li>Simplicidade</li>
<li>Independe do <a href="https://pt.wikipedia.org/wiki/Sistema_de_gerenciamento_de_banco_de_dados">SGDB</a> a ser utilizado</li>
<li>Mundo real a ser mapeado (mini-mundo) pode ser visto como um conjunto de entidades e de relacionamentos entre as mesmas.</li>
<li>Desenvolvido para facilitar o projeto de banco de dados</li>
<li>Especifica "<strong>quais</strong>" os dados serão representados (O QUE) e não "<strong>como</strong>" os dados serão armazenados.</li>
<li>Elementos do modelo:
<ul>
<li>Entidades</li>
<li>Relacionamentos</li>
<li>Atributos</li>
</ul>
</li>
</ul>
<h1>Entidade</h1>
<p>Qualquer objeto, pessoa, lugar, conceito ou "coisa" no mundo real com uma existência própria/independente e sobre a qual seja necessário armazenar informações ou características.</p>
<p>Pode ter uma <strong>existência física</strong> (<em>um rio, uma estrada, uma casa, um aluno, um carro, um cantor...</em>) ou uma <strong>existência conceitual</strong> (<em>um cargo, um curso, um evento..</em>).</p>
<p><strong>SÍMBOLO</strong>: <em>Utiliza-se um <strong>retângulo</strong> para representar uma entidade, geralmente o nome é escrito no singular.</em></p>
<h2>Entidade Fraca</h2>
<p>Caracterizada pela sua dependência da existência de outra entidade.<br>
Uma entidade fraca não possui características o suficiente para existir "sozinha".</p>
<p><strong>SÍMBOLO</strong>: <em>Utilizamos um retângulo inscrito em outro retângulo para representarmos uma entidade fraca</em></p>
<h1>Relacionamento</h1>
<p>Um relacionamento descreve um associação entre suas ou mais entidades <strong>(ação)</strong></p>
<p><strong>SÍMBOLO</strong>: <em>Utilizamos um <strong>lozango</strong> para representarmos um relacionamento</em></p>
<h2>Relacionamento dependente</h2>
<p>O relacionamento dependente é usado quando queremos relacionar uma ENTIDADE com uma <a href="#entidade-fraca">ENTIDADE FRACA</a>.</p>
<p><strong>SÍMBOLO</strong>: <em>Utilizamos um losango inscrito a outro losango para representar um relacionamento dependente</em></p>
<h1>Atributo</h1>
<p>O atributo é cada característica, propriedade ou qualidade específica que descreve e/ou relacionamento.</p>
<p><strong>Isto é...</strong></p>
<ul>
<li>A entidade <strong><code>EMPREGADO</code></strong> poderia ter os atributos: <code>nome</code>, <code>endereço</code>, <code>data de nascimento</code>, <code>salário</code> e <code>profissão</code>.</li>
<li>A entidade <strong><code>EMPRESA</code></strong> poderia ter os atributos: <code>nome</code>, <code>razão social</code>, <code>CNPJ</code>, <code>matriz</code>, <code>presidente</code>, <code>endereço</code>, <code>telefone</code>.</li>
<li>A entidade <strong><code>CARRO</code></strong> poderia ter os atributos: <code>fabricante</code>, <code>modelo</code>, <code>ano de fabricação</code>, <code>cor</code>, <code>número de portas</code>, <code>placa</code>, <code>chassi</code>.</li>
</ul>
<p><strong>SÍMBOLO</strong>: <em>Utilizamos uma elípse (círculo ovulado) para representarmos um atributo.</em></p>
<p>Representação gráfica dos atributos da entidade <strong><code>CLIENTE</code></strong>:<br>
<br>
</p>
<h2>ATRIBUTO CHAVE ou CHAVE</h2>
<p>São atributos ou conjunto de atributos que identifica <strong>unicamente</strong> e <strong>exclusivamente</strong> uma entidade, ou seja, não há valores repetidos desse atributo na entidade. Sendo assim, o seu valor pode ser usado para identificar cada entidade.</p>
<p>Alguns tipode de entidades podem ter mais que um atributo-chave, exêmplo: CPF, identidade, matrícula, CIU.</p>
<p>O atributo chave deve aparecer sublinhado em sua simbologia.</p>
<h3>ATRIBUTO CHAVE PARCIAL ou CHAVE PARCICAL</h3>
<p><strong>TL;DR</strong>: chamamos de chave-parcial o atributo chave de uma <a href="#entidade-fraca">entidade-fraca</a></p>
<p>Uma <a href="#entidade-fraca">entidade-fraca</a> tem uma <strong>chave-parcial</strong>, que é um atributo (ou conjunto de atributos) que podem univocadamente identificar entidades-fracas relacionadas à uma entidade (forte).</p>
<p>Um tipo de entidade-fraca pode, algumas vezes, ser representado como atributo composto (endereço).</p>
<p>A escolha de qual representação usar é determinada pelo projetista do banco de dados.</p>
<h2>Atributo simple ou atômico</h2>
<p>São atributos que não são divisíveis, representam uma informação exata e direta, e que não são possíveis de serem decompostos em mais atributos.</p>
<h2>Atributo composto</h2>
<p>É um atribusto que pode ser composto de outros atributos mais básicos.</p>
<h2>Atributo multivalorado</h2>
<p>São atributos que possuem um ou mais valores <strong>de um mesmo tipo</strong></p>
<p><strong>SÍMBOLO</strong>: <em>Um círculo ovalado dentro de outro círculo ovalado</em></p>
<p><strong>Exemplo 2</strong><br>
Um atributo <code>idioma</code> de uma entidade <strong><code>ALUNO</code></strong> pode conter os valores inglês e francês. Para um outro aluno poderia conter apenas um valor, como espanhol. Para um terceiro aluno, poderíamos ter 3 valores para esse atributo: inglês, francês e espanhol.<br>
</p>
<h2>Atributo derivado</h2>
<p>Este tipo de atributo é derivado de outros atributos.</p>
<p>Não necessitam serem armazenados na base de dados, podendo ser calculados apartir de um consulta através da aplicação.</p>
<p>O atributo <code>idade</code> de uma <strong><code>PESSOA</code></strong>. Para uma pessoa em particular, podemos determinar o valor atual de idade através do atributo <code>data_nascimento</code> e da data atual do sistema operacional.</p>
<p>Então a <code>idade</code> é chamada atributo derivado, pois pode ser obtida de outros atributos.<br>
</p>
<p><strong>SÍMBOLO</strong>: <em>Círculo ovalado com contorno pontilhado.</em></p>
<h1>Boas práticas: Sujestão para nomes</h1>
<p>A literatura não define um padrão, mas algumas práticas são usadas:</p>
<h2>Entidades</h2>
<ul>
<li>Nomes breves e objetivos, com letras maiúsculas que identifique facilmente o conteúdo da entidade;</li>
<li>No singular, já que a pluralidade decorre, naturalmente, do número de ocorrências, característica própria de toda entidade;</li>
<li>Nomes compostos separados por hífen <code>-</code>, eliminando-se o uso de preposições ou outros termos de ligação.</li>
</ul>
<h2>Relacionamentos</h2>
<ul>
<li>Palavras escritas com letras minúsculas;</li>
<li>Palavras compostas use <em>underline</em> <code>_</code>.</li>
</ul>
<h2>Atributos</h2>
<ul>
<li>Primeira letra do nome maiúscula e o restante mínúscula;</li>
<li>Palavras compostas use <em>underline</em> <code>_</code>;</li>
<li>Palavras repetidas em outras entidades, use a inicial da entidade no início e continue com o nome. Ex.: <code>Empr_Nome</code> para o nome da <strong><code>EMPRESA</code></strong>, <code>Dept_Nome</code> para o nome do <strong><code>DEPARTAMENTO</code></strong>.</li>
</ul>
<h1>Praticando</h1>
<h2>Controle de professores FAPAM</h2>
<p>A FAPAM precisa ter controle de seus professores e quais turmas eles estão lecionando. Para isso ela precisa saber do professor o nome, CPF e o salário. Já de suas turmas, a faculdade precisa saber a descrição, quantos alunos possui e a carga horária.</p>
<h2>Instituição de Ensino</h2>
<p>Fomos contratados por uma instituição, e a mesma, precisa ter um sistema para controle de cursos, sabemos que precisamos ter informações dos alunos, dos cursos e de professores. De cada aluno, será necessário armazenar: seu nome, matrícula, data de nascimento e idade. De cada curso será necessário armazenar a descrição e quantidade de alunos inscritos. Do professor, o seu nome e CPF.</p>
<h1>Tipos de relacionamento</h1>
<p>Os tipos de relacionamento estão associados ao conceito denominado <strong>cardinalidade</strong>.</p>
<p>A <strong>cardinalidade</strong> é a quantidade de ocorrências que uma entidade pode ter em relação a outra entidade.</p>
<p><strong>Cardinalidade nos RELACIONAMENTOS</strong>:</p>
<ul>
<li>Relacionamento <strong>1:1</strong> <em>Lê se UM PARA UM</em></li>
<li>Relacionamento <strong>1:N</strong> <em>Lê se UM PARA MUITOS</em></li>
<li>Relacionamento <strong>N:M</strong> ou <strong>N:N</strong> <em>Lê se MUITOS PARA MUITOS</em></li>
</ul>
<h2>Relacionamento 1:1</h2>
<p>Um relacionamento 1:1 é um relacionamento onde UMA entidade está associada a UMA outra entidade, e vice-versa.</p>
<h2>Relacionamento 1:N</h2>
<p>Um relacionamento 1:N é um relacionamento onde UMA entidade está associada a MUITAS outras entidades, mas as entidades associadas estão associadas a apenas UMA entidade.</p>
<h2>Relacionamento N:M</h2>
<p>Um relacionamento N:M é um ripelacionamento onde MUITAS entidades estão associadas a MUITAS outras entidades.</p>
<h2>Par de cardinalidades</h2>
<p>Alguns livros trazem a notação de par de cardinalidade, que de define através da atribuição de um valor mínimo e um valor máximo para os tipos de relacionamentos existentes.</p>
<blockquote>
<p>Um empregado <strong>obrigatóriamente está</strong> lotado no máximo em 1 departamento. Um departamento <strong>pode ter</strong> até N empregados lotados nele.</p>
</blockquote>
<h2>Atributos em relacionamentos</h2>
<p>Os relacionamentos também podem ter atributos. Por exemplo: pode haver a necessidade de representar a quantidade de <strong>horas semanais</strong> trabalhadas pode um empregado em um dado projeto. Isto pode ser representado no relacionamento <code>trabalha_em</code> na forma do atributo denominado <code>Horas</code></p>
<h1>Praticando</h1>
<h2>Projetos de uma empresa</h2>
<p>Numa empresa os funcionários são descritos por um nome, número do CPF, salário, endereço (logradouro, número, bairro, cidade), data de nascimento e sexo. Tanto o número do CPF possui valor exclusivo para cada funcionário.</p>
<p>Os funcionários pertencem a departamentos da empresa. Cada departamento possui um nome, um número, uma localização e uma sigla que o identifica. Esta sigla é exclusiva de cada departamento.</p>
<p>Cada departamento é supervisionado por um funcionário da empresa. É necessário saber a data de início da supervisão, para que a cada dois anos haja substituições.</p>
<p>Os departamentos possuem projetos associados. Cada projeto é identificado por um nome, um código e um número de funcionários alocados. O código do projeto é exclusivo para cada um deles.</p>
<p>Os funcionários da empresa trabalham em projetos, e o número de horas dedicadas a um determinado projeto deve ser armazenado no BD.</p>
<h2>Cia de seguros de automóveis</h2>
<p>Uma <strong>cia de seguros de automóveis</strong> possui vários cliente (nome, endereço, CPF, e telefone(s)), cada um deles são proprietários de um ou mais veículos (fabricante, modelo, ano, placa, estado).</p>
<p>Cada carro está associado a nenhum ou vários registros de acidentes (data, número do BO). Um acidente pode evolver não apenas um, mas vários carros.</p>
<h1>Multi Relacionamentos</h1>
<p>Um relacionamento liga duas entidades, porém, é possível que uma entidade se relacione com outra entidade mais de uma vez.</p>
<p><br>
</p>
<h1>Auto relacionamento</h1>
<p>O auto relacionamento, também chamado de <strong>relacionamento recursivo</strong>, ocorre quando uma entidade se relaciona consigo mesma.</p>
<h2>Auto relacionamento (1:N)</h2>
<p>O relacionamento <code>supervisiona</code> relaciona um empregado com o seu supervisor, onde ambas entidades são membros do mesmo tipo de entidade <strong><code>EMPREGADO</code></strong>. Assim, o tipo de entidade EMPREGADO participa duas vezes: uma vez no papel de supervisor e outra no papel de supervisionado. Assim, <code>e1</code> supervisiona <code>e2</code>, <code>e2</code> supervisiona <code>e3</code> e <code>e1</code> supervisiona <code>e4</code>.</p>
<p><br>
</p>
<h2>Auto relacionamento (N:N) e (1:1)</h2>
<blockquote>
<p>Cada disciplina pode ter um ou mais pré-requisitos (disciplinas), e cada disciplina pode ser pré-requisito de uma ou mais disciplinas.</p>
</blockquote>
<blockquote>
<p>Cada pessoa casa com uma pessoa, e cada pessoa é casada com uma pessoa. <del>na maioria dos casos</del></p>
</blockquote>
<p><br>
</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>mer</category>
            <category>fapam</category>
            <category>database</category>
            <category>diagrama</category>
            <category>gti</category>
            <category>modelo</category>
            <category>entidade-relacionamento</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/mer-modelo-de-entidade-relacionamento-1/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Exercícios GTI P1 - Programação Estruturada]]></title>
            <link>https://mateusf.com/blog/post/exercicios-gti-p1-programacao-estruturada</link>
            <guid>exercicios-gti-p1-programacao-estruturada</guid>
            <pubDate>Mon, 04 Mar 2024 12:35:34 GMT</pubDate>
            <description><![CDATA[Exercícios das aulas de Programação Estruturada, do curso GTI na FAPAM, 1º Período.]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/exercicios-gti-p1-programacao-estruturada/thumbnail" alt=""> Esta é a lista de exercícios da matéria de <strong>Programação Estruturada</strong>, do curso de <strong>Gestão de TI</strong>, feito na <a href="https://fapam.edu.br">FAPAM - Faculdade de Pará de Minas</a>.</p>
<h1>Introdução</h1>
<p>De início estamos usando o Portugol Visualg, você pode baixar a versão 3.06 <a href="assets/visualg3.06.rar">aqui</a>, apenas para Windows.</p>
<p>Todos os códigos também vão estar em um repositório espelho no Github: <a href="https://github.com/mateusfg7/atividades-programacao-estruturada-fapam">https://github.com/mateusfg7/atividades-programacao-estruturada-fapam</a></p>
<p>Pra quem usa VSCode, pode instalar a extensão <a href="https://marketplace.visualstudio.com/items?itemName=designliquido.designliquido-vscode">Design Líquido - Linguagens em Português</a> para ter <em>syntax hightlight</em> em linguagens em português e outros dialetos de Portugol (Portugol Studio, Postugol VisuAlg, BRIL, êtc.).</p>
<h1>Dicas Visualg</h1>
<h2>Atalhos</h2>
<table>
<thead>
<tr>
<th>Descrição</th>
<th>Atalho</th>
</tr>
</thead>
<tbody>
<tr>
<td>Formatar automaticamente</td>
<td>CTRL + G</td>
</tr>
<tr>
<td>Rodar programa</td>
<td>F9</td>
</tr>
</tbody>
</table>
<h1>Aula 2 - VisuAlg</h1>
<p><strong>Data</strong>: 15/02/2024</p>
<h2>Exercício 1</h2>
<blockquote>
<p>Escreva um algoritmo que leia as três notas do aluno, calcule e imprima no console a média que ele obteve na disciplina.</p>
</blockquote>
<pre><code class="language-visualg">algoritmo "MediaNotas"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor Cristiano Queiroz
// Descrição   : Algoritmo que lê as três notas do aluno,
//               calcula e imprima no console a média que
//               ele obteve na disciplina.
// Autor(a)    : Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual  : 16/02/2024

var
   primeira_nota: inteiro
   segunda_nota:  inteiro
   terceira_nota: inteiro
   media: real
   loop:  caractere

inicio
   loop &#x3C;- "sim"

   enquanto (loop = "sim") faca
      limpatela()
      escreval("-----| NOTAS |-----")
      escreval("")

      escreva("Primeira Nota --- ")
      leia(primeira_nota)
      escreva("Segunda Nota ---- ")
      leia(segunda_nota)
      escreva("Terceira Nota --- ")
      leia(terceira_nota)

      escreval("")

      media &#x3C;- (primeira_nota+segunda_nota+terceira_nota)/3
      escreval("MÉDIA:", media)

      escreval("")
      escreval("-------------------")
      escreval("")
      escreval("Nova consulta? [sim|nao]")
      escreva("-> ")
      leia(loop)
   fimenquanto

fimalgoritmo
</code></pre>
<h2>Exercício 2</h2>
<blockquote>
<p>Sabe-se que o m² de construção custa R$850. Escreva um algoritmo que leia as medidas de um terreno retangular e calcule e imprima quanto custa para construir uma casa que ocupe todo esse terreno.</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "ValorM²"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor Cristiano Queiroz
// Descrição   : Algoritmo que lê as medidas de um
//               terreno retangular e calcule e imprime quanto
//               custa para construir uma casa que ocupe todo
//               esse terreno.
// Autor(a)    : Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual  : 16/02/2024
Var

   VALOR_METRO_QUADRADO: real
   escolher_valor:       caractere

   altura_terreno:       real
   largura_terreno:      real

Inicio
   VALOR_METRO_QUADRADO &#x3C;- 850

   escreval("-| FORMULARIO |-------------------------")
   escreval("")

   escreval("Largura do terreno (m)")
   escreva("-> ")
   leia(largura_terreno)

   escreval("")

   escreval("Altura do terreno (m)")
   escreva("-> ")
   leia(altura_terreno)

   escreval("")

   escreval("Escolher valor do m²? (Padrão: R$850.00)")
   escreva("[sim|nao] -> ")
   leia(escolher_valor)

   escreval("")

   se escolher_valor = "sim" entao
      escreval("Valor do m² (Ex.: 900.00)")
      escreva("-> ")
      leia(VALOR_METRO_QUADRADO)

      escreval("")
   fimse

   escreval("-| RESULTADOS |-------------------------")
   escreval("")

   escreval("Tamanho do terreno  =", altura_terreno*largura_terreno, "m²")
   escreval("Custo de construção = R$", (altura_terreno*largura_terreno)*VALOR_METRO_QUADRADO)

   escreval("")
   escreval("----------------------------------------")
Fimalgoritmo
</code></pre>
<h2>Exercício 3</h2>
<blockquote>
<p>Escreva um algoritmo que leia o salário total de uma pessoa e quantas horas ela trabalha por dia, em seguida, calcule e imprima quanto essa pessoa recebe por hora. Considere o mês com 30 dias.</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "CalcularSalario"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor Cristiano Queiroz
// Descrição   : Algoritmo que lê o salário total de
//               uma pessoa e quantas horas ela trabalha por dia,
//               e calcula e imprime quanto essa pessoa
//               recebe por hora.
// Autor(a)    : Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual  : 16/02/2024
Var
   DIAS_NO_MES: inteiro
   dias_uteis:  inteiro

   salario:       real
   horas_por_dia: inteiro

   horas_por_mes:    inteiro
   salario_por_hora: real

Inicio
   DIAS_NO_MES &#x3C;- 30

   escreval("-| CALCULAR SALÁRIO |------")
   escreval("")

   escreval("Seu salário (Ex.: 1400.00)")
   escreva("-> ")
   leia(salario)

   escreval("")

   escreval("Horas de trabalho (Ex.: 8)")
   escreva("-> ")
   leia(horas_por_dia)

   escreval("")

   // 4 semanas no mês, sábado e domingo não conta, ou seja:
   // 4*2 = 8 dias não úteis
   dias_uteis &#x3C;- DIAS_NO_MES - 8
   horas_por_mes &#x3C;-  dias_uteis * horas_por_dia

   salario_por_hora &#x3C;- salario/horas_por_mes

   escreva("Seu valor /hora = R$", salario_por_hora)

   escreval("")
Fimalgoritmo
</code></pre>
<h2>Exercício 4</h2>
<blockquote>
<p>Escreva um algoritmo que peça ao usuário para informar o peso e a altura com o comando leia, depois calcule e imprima na tela o IMC dessa pessoa sabendo que a fórmula do IMC é (peso/altura²).</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "CalculaIMC"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor Cristiano Queiroz
// Descrição   : Calcula IMC de uma pessoa
// Autor(a)    : Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual  : 16/02/2024
Var
   preso_em_km:  real
   altura_em_cm: inteiro

   IMC: inteiro

Inicio
   escreval("# CALCULADORA IMC ########")
   escreval("")

   escreval("Seu peso /Kg (Ex.: 59.9)")
   escreva("-> ")
   leia(preso_em_km)

   escreval("")

   escreval("Altura /cm (Ex.: 170)")
   escreva("-> ")
   leia(altura_em_cm)

   escreval("")

   escreval("# RESULTADOS #############")
   escreval("")

   escreval("Seu IMC =", preso_em_km/((altura_em_cm/100)^2))

   escreval("")
   escreval("##########################")
Fimalgoritmo
</code></pre>
<h1>Aula 3 - VisuAlg</h1>
<p><strong>Data</strong>: 22/02/2024</p>
<h2>Exercício 1</h2>
<blockquote>
<p>Desenvolva um software que receba uma idade do usuário e imprima na tela se ele é maior de idade ou menor de idade.</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "Idade"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor Cristiano
// Descrição   : Determina se o usuário é maior de idade ou não
// Autor(a)    : Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual  : 23/02/2024
Var
   idade: inteiro

Inicio
   escreval("Sua idade")
   escreva("-> ")
   leia(idade)

   escreval("")

   se (idade >= 18) entao
      escreva("Maior de idade")
   senao
      escreva("Menor de idade")
   fimse

   escreval("")
Fimalgoritmo
</code></pre>
<h2>Exercício 2</h2>
<blockquote>
<p>Desenvolva um software que receba um nome e o sexo do usuário, após imprima na tela uma saudação conforme o sexo do usuário, EX: “Bem Vindo José” ou “Bem Vinda Maria”.</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "Saudação"
// Disciplina: Programação Estruturada
// Professor:  Adjenor Cristiano
// Descrição:  Saudações
// Autor(a):   Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual: 23/02/2024
Var
   nome: caractere
   sexo: caractere

Inicio
   escreval("Seu nome")
   escreva("-> ")
   leia(nome)

   escreval("")

   escreval("Seu sexo (apenas letra) | Ex.: M")
   escreval("[M] Masculino")
   escreval("[F] Feminino")
   escreva("-> ")
   leia(sexo)

   escreval("")

   se (sexo = "M") entao
      escreva("Bem Vindo ", nome, "!")
   senao
      escreva("Bem Vinda ", nome, "!")
   fimse

   escreval("")
Fimalgoritmo
</code></pre>
<h2>Exercício 3</h2>
<blockquote>
<p>Doar sangue é uma atitude muito importante, entretanto é preciso atender alguns requisitos para poder doar sangue.</p>
<ul>
<li>Ter entre 19 e 69 anos de idade</li>
<li>Pesar ao menos 50 kg</li>
<li>Não ter feito nenhuma tatuagem no último ano</li>
<li>Não ter ingerido álcool nas últimas 12 horas.</li>
</ul>
<p>Desenvolva um software que pergunte ao usuário se ele atende os requisitos necessários para doar sangue. Faça as perguntas uma por vez, caso a resposta dele o impeça de doar, avise-o e encerre o sistema. Se ele atender todos os requisitos, aviseo que ele pode ser doador.</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "Doacao"
// Disciplina: Programação Estruturada
// Professor:  Adjenor Cristiano
// Descrição:  Verifica disponibilidade de doação
// Autor(a):   Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual: 23/02/2024
Var
   idade:          inteiro
   peso:           real
   fez_tatuagem:   caractere
   ingeriu_alcool: caractere

Inicio
   escreval("Sua idade")
   escreva("-> ")
   leia(idade)
   escreval("")

   se ((idade &#x3C; 19) OU (idade > 69)) entao
      escreval("Você deve ter entre 19 e 69 anos para doar sangue!")
      Fimalgoritmo
   fimse

   escreval("Seu peso (Kg)")
   escreva("-> ")
   leia(peso)
   escreval("")

   se (peso &#x3C; 50.0) entao
      escreval("Você deve ter pelomenos 50Kg para doar sangue!")
      Fimalgoritmo
   fimse

   escreval("Fez tatuagem no último ano")
   escreva("[sim|nao]-> ")
   leia(fez_tatuagem)
   escreval("")

   se (NAO(fez_tatuagem = "nao")) entao
      escreval("Você não pode doar sangue se tiver feito tatuagem no último ano!")
      Fimalgoritmo
   fimse

   escreval("Ingeriu alcool nas últimas 12 horas")
   escreva("[sim|nao]-> ")
   leia(ingeriu_alcool)
   escreval("")

   se (NAO(ingeriu_alcool = "nao")) entao
      escreval("Você não pode doar sangue se tiver bebido nas últimas 12 horas!")
      Fimalgoritmo
   fimse

   escreval("")
   escreval("Você pode ser um doador!")
   escreval("")
Fimalgoritmo
</code></pre>
<h2>Exercício 4</h2>
<blockquote>
<p>Crie um software que ajude a polícia rodoviária federal calcular o valor das multas dos motoristas. O software deve perguntar ao usuário qual a velocidade permitida e qual a velocidade do motorista.<br>
Se o motorista estiver acima da velocidade permitida, o software deve informar qual o tipo de infração e qual o valor da multa. Se o motorista estiver dentro do limite permitido, o programa encerra dizendo que ele não precisa pagar multa. Veja abaixo os valores de multas reajustados de infração por excesso de velocidade:</p>
<ul>
<li>Exceder velocidade em até 20% (infração média) = R$85,00 + 4 pontos</li>
<li>Exceder velocidade de 20 até 50% (infração grave) = R$127,00 + 5 pontos;</li>
<li>Exceder velocidade acima de 50% (infração gravíssima) = R$574,00 + 7 pontos + apreensão da carteira + suspensão do direito de dirigir.</li>
</ul>
</blockquote>
<pre><code class="language-visualg">Algoritmo "CalcularMulta"
// Disciplina: Programação Estruturada
// Professor:  Adjenor Cristiano
// Descrição:  Calcular Multa
// Autor(a):   Mateus Felipe Gonçalves  &#x3C;contato@mateusf.com>
// Data atual: 23/02/2024
Var
   velocidade_permitida: inteiro
   velocidade_motorista: inteiro
   excedente: real

Inicio
   escreval("Velocidade máxima permitida (Km/h)")
   escreva("-> ")
   leia(velocidade_permitida)
   escreval("")

   escreval("Velocidade do motorista (Km/h)")
   escreva("-> ")
   leia(velocidade_motorista)
   escreval("")

   escreval("---------------------------------")
   escreval("")

   se (velocidade_motorista &#x3C;= velocidade_permitida) entao
      escreva("Você não precisará pagar multa! ;)")
   senao
      excedente &#x3C;- ((velocidade_motorista-velocidade_permitida)/velocidade_permitida)*100
      escreval("Você excedeu a velocidade máxima permitida em ", excedente:2:0, "%")
      escreval("")
      se (excedente &#x3C;= 20.0) entao
         escreval("INFRAÇAO MÉDIA")
         escreval("")

         escreval("Sua multa é de R$85,00")
         escreval("+ 4 pontos")
      senao
         se (excedente &#x3C;= 50.0) entao
            escreval("INFRAÇAO GRAVE")
            escreval("")

            escreval("Sua multa é de R$127,00")
            escreval("+ 5 pontos")
         senao
            escreval("INFRAÇAO GRAVÍSSIMA")
            escreval("")

            escreval("Sua multa é de R$574,00")
            escreval("+ 7 pontos")
            escreval("Suspensão do direito de dirigir")
         fimse
      fimse
   fimse
Fimalgoritmo
</code></pre>
<h2>Exercício 5</h2>
<blockquote>
<p>Uma loja de salgadinhos precisa de ajuda para calcular o valor da conta dos clientes. Crie um programa que leia o código do produto que o cliente comprou e a quantidade e informe a ele quanto ele deverá pagar. Faça uso da estrutura ESCOLHA-CASO. A Tabela abaixo apresenta o código, a descrição e o preço de cada salgadinho.</p>
</blockquote>
<table>
<thead>
<tr>
<th>Código</th>
<th>Descrição</th>
<th>Preço unitário</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Coxinha</td>
<td>0,50</td>
</tr>
<tr>
<td>2</td>
<td>Pastel</td>
<td>0,75</td>
</tr>
<tr>
<td>3</td>
<td>Pão de queijo</td>
<td>0,40</td>
</tr>
<tr>
<td>4</td>
<td>Enroladinho</td>
<td>0,80</td>
</tr>
</tbody>
</table>
<pre><code class="language-visualg">Algoritmo "CalcularConta"
// Disciplina: Programação Estruturada
// Professor:  Adjenor Cristiano
// Descrição:  Calcula Conta do Cliente
// Autor(a):   Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual: 23/02/2024
Var
   id_do_produto: inteiro
   quantidade:    real
   total:         real

   loop: caractere

Inicio
   loop &#x3C;- "sim"

   enquanto (loop = "sim") faca
      loop &#x3C;- "nao"

      limpatela()
      escreval("+---------------------------------------+")
      escreval("|               SALGADOS                |")
      escreval("|---------------------------------------|")
      escreval("| Cód. |    Salgado    | Valor unitário |")
      escreval("|---------------------------------------|")
      escreval("| [1]  | Coxinha       |     R$0,50     |")
      escreval("| [2]  | Pastel        |     R$0,75     |")
      escreval("| [3]  | Pão de Queijo |     R$0,40     |")
      escreval("| [4]  | Enroladinho   |     R$0,80     |")
      escreval("+---------------------------------------+")
      escreval("")
      escreva("Cód. -> ")
      leia(id_do_produto)
      escreva("Qtd. -> ")
      leia(quantidade)

      escolha id_do_produto
      caso 1
         total &#x3C;-  quantidade*0.50
      caso 2
         total &#x3C;-  quantidade*0.75
      caso 3
         total &#x3C;-  quantidade*0.40
      caso 4
         total &#x3C;-  quantidade*0.80
      fimescolha

      escreval("")
      escreval("TOTAL: R$", total:4:2)
      escreval("")

      escreval("Nova compra?")
      escreva("[sim|nao]-> ")
      leia(loop)
   fimenquanto
Fimalgoritmo
</code></pre>
<h1>Aula 4 - VisuAlg</h1>
<p><strong>Data</strong>: 29/02/2024</p>
<h2>Exercício 1</h2>
<blockquote>
<p>Crie um software que receba do usuário um valor inteiro e imprima na tela o mês do ano correspondente ao valor recebido (ex. recebendo o valor 1, o programa imprime “Janeiro”; recebendo o valor 2, o programa imprime “Fevereiro”...).</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "Meses"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor Cristiano
// Descrição   : Imprime o mês referente à um ID
// Autor(a)    : Mateus Felipe Gonçalves
// Data atual  : 03/03/2024
Var
   // Seção de declaração de variáveis
   id: inteiro

Inicio
   // Seção de Comandos, procedimento, funções, operadores, etc...
   escreval("Digite o número do mês")
   escreva("-> ")
   leia(id)

   escreval("")

   escolha(id)
   caso 1
      escreval("Janeiro")
   caso 2
      escreval("Fevereiro")
   caso 3
      escreval("Março")
   caso 4
      escreval("Abril")
   caso 5
      escreval("Maio")
   caso 6
      escreval("Junho")
   caso 7
      escreval("Julho")
   caso 8
      escreval("Agosto")
   caso 9
      escreval("Setembro")
   caso 10
      escreval("Outubro")
   caso 11
      escreval("Novembro")
   caso 12
      escreval("Dezembro")
   outrocaso
      escreval("ID Inválido!")
   fimescolha
Fimalgoritmo
</code></pre>
<h2>Exercício 2</h2>
<blockquote>
<p>Crie um software que receba do usuário um valor inteiro de 1 a 10 e imprima na tela o número por extenso. Se o usuário digitar um número maior que 10 ele deve imprimir “Valor Inválido”.</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "Numero"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor Cristiano Queiroz
// Descrição   : Número por extenso
// Autor(a)    : Mateus Felipe Gonçalves
// Data atual  : 03/03/2024
Var
   // Seção de declaração de variáveis
   id: inteiro

Inicio
   // Seção de Comandos, procedimento, funções, operadores, etc...
   escreval("Digite o número")
   escreva("-> ")
   leia(id)

   escreval("")

   escolha(id)
   caso 1
      escreval("Um")
   caso 2
      escreval("Dois")
   caso 3
      escreval("Três")
   caso 4
      escreval("Quatro")
   caso 5
      escreval("Cinco")
   caso 6
      escreval("Seis")
   caso 7
      escreval("Sete")
   caso 8
      escreval("Oito")
   caso 9
      escreval("Nove")
   caso 10
      escreval("Dez")
   outrocaso
      escreval("Valor inválido!")
   fimescolha

Fimalgoritmo
</code></pre>
<h2>Exercício 3</h2>
<blockquote>
<p>Desenvolva um software que receba o nome do usuário, o sexo, a cidade e o ano que ele nasceu e depois imprima na tela sua ficha cadastral utilizando “Sr” para homens e “Srª” para mulheres.<br>
Considere apenas o ano para cálculo da idade (quem nasceu em 2002 considere que ele tem 22 anos, quem nasceu em 2001 considere 23...)<br>
Ex: Ficha Cadastral<br>
Sr: Adjenor Cristiano Queiroz<br>
Idade: 22 anos<br>
Cidade: Pará de Minas</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "Ficha"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor Cristiano
// Descrição   : Imprime o mês referente à um ID
// Autor(a)    : Mateus Felipe Gonçalves
// Data atual  : 03/03/2024
Var
   // Seção de declaração de variáveis
   nome:        caractere
   sexo:        caractere
   cidade:      caractere
   ano_nasc:    inteiro
   comprimento: caractere

Inicio
   escreval("Nome")
   escreva("-> ")
   leia(nome)
   escreval("")

   escreval("Sexo [M|F]")
   escreva("-> ")
   leia(sexo)
   escreval("")

   escreval("Cidade")
   escreva("-> ")
   leia(cidade)
   escreval("")

   escreval("Ano de nascimento")
   escreva("-> ")
   leia(ano_nasc)
   escreval("")

   se ano_nasc > 2024 entao
      escreval("ERRO | O ano de nascimento não pode ser no futuro")
      interrompa()
   fimse

   se maiusc(sexo) = "M" entao
      comprimento &#x3C;- "Sr."
   senao
      comprimento &#x3C;- "Srª."
   fimse

   escreval("FICHA CADASTRAL")
   escreval(comprimento, " -- ", nome)
   escreval("Idade --", 2024 - ano_nasc)
   escreval("Cidade - ", cidade)
Fimalgoritmo
</code></pre>
<h2>Exercício 4</h2>
<blockquote>
<p>(DESAFIO) Desenvolva um Software para um restaurante que irá mostrar para o usuário um cardápio de refeições (com no mínimo 4 opções) para escolha:</p>
<p>Ex:<br>
1 – Risotto ----- R$ 25,00<br>
2 – Espaguete --- R$ 22,00</p>
<p>Depois pergunte a ele se ele deseja alguma bebida. Se ele desejar, mostre a ele um menu com as opções de bebida (ao menos 4).</p>
<p>Ex:<br>
1 – Coca Cola -------- R$ 5,00<br>
2 – Água Mineral ----- R$ 3,00<br>
Ao final mostre a ele qual o seu pedido e o valor da conta.</p>
<p>Ex: PEDIDO:<br>
Espaguete R$ 22,00<br>
Coca Cola R$ 5,00<br>
TOTAL: R$ 27,00.</p>
<p>Dica: Use uma variável do tipo caractere para armazenar os itens do pedido e uma variável real para armazenar os valores</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "Cardápio"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor Cristiano
// Descrição   : Imprime o mês referente à um ID
// Autor(a)    : Mateus Felipe Gonçalves
// Data atual  : 03/03/2024
Var
   prato: inteiro
   bebida: inteiro
   quer_bebida: caractere
   total: real
Inicio
   escreval("------------ PRATOS ------------")
   escreval("[1] Risoto ------------- R$25,00")
   escreval("[2] Espaguete ---------- R$22,00")
   escreval("[3] Strogonoff --------- R$30,00")
   escreval("[4] Macarrão na Chapa -- R$20,00")
   escreval("")
   escreva("-> ")
   leia(prato)
   escreval("")

   escreval("Aceita uma bebida? [S|N]")
   escreva("-> ")
   leia(quer_bebida)
   escreval("")

   se maiusc(quer_bebida) = "S" entao
      escreval("--------- BEBIDAS ---------")
      escreval("[1] Água Mineral -- R$ 3,00")
      escreval("[2] Coca Cola ----- R$ 5,00")
      escreval("[3] Limonada ------ R$ 5,00")
      escreval("[4] Jack&#x26;Coffee --- R$25,00")
      escreval("")
      escreva("-> ")
      leia(bebida)
      escreval("")
   fimse

   escreval("---------- PEDIDO ----------")
   escolha(prato)
   caso 1
      total &#x3C;- 25.00
      escreval("Risoto ------------- R$25,00")
   caso 2
      total &#x3C;- 22.00
      escreval("Espaguete ---------- R$22,00")
   caso 3
      total &#x3C;- 30.00
      escreval("Strogonoff --------- R$30,00")
   caso 4
      total &#x3C;- 20.00
      escreval("Macarrão na Chapa -- R$20,00")
   fimescolha

   se maiusc(quer_bebida) = "S" entao
      escolha(bebida)
      caso 1
         total &#x3C;- total + 3.00
         escreval("Água Mineral ------- R$ 3,00")
      caso 2
         total &#x3C;- total + 5.00
         escreval("Coca Cola ---------- R$ 5,00")
      caso 3
         total &#x3C;- total + 5.00
         escreval("Limonada ----------- R$ 5,00")
      caso 4
         total &#x3C;- total + 25.00
         escreval("Jack&#x26;Coffee -------- R$25,00")
      fimescolha
   fimse

   escreval("")
   escreval("TOTAL: R$", total:2:2)
Fimalgoritmo
</code></pre>
<h1>Aula 5 - VisuAlg</h1>
<p><strong>Data</strong>: 05/03/2024</p>
<h2>Exercício 1</h2>
<blockquote>
<p>Desenvolva um software em que receberá alguns números fornecidos pelo usuário, enquanto ele quiser continuar digitando números (a cada interação pergunte ao usuário se ele deseja continuar a soma), e ao final, exiba o resultado da soma dos números digitados na tela.</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "SomaNumeros"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor Cristino
// Descrição   : Soma vários números fornecidos pelo usuário
// Autor(a)    : Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual  : 08/03/2024
Var
   soma:   inteiro
   numero: inteiro
   continuar: caractere
   primeira_interacao: logico

Inicio
   continuar &#x3C;- "SIM"
   primeira_interacao &#x3C;- verdadeiro
   numero &#x3C;- 0
   soma &#x3C;- 0

   enquanto (maiusc(continuar) = "SIM") faca
      limpatela()

      se(primeira_interacao) entao
         primeira_interacao &#x3C;- falso

         escreval("Digite um número")
         escreva("-> ")
         leia(numero)
      senao
         escreval("Digite mais um número")
         escreva("-> ")
         leia(numero)
      fimse

      soma &#x3C;- soma + numero

      escreval()

      escreval("Deseja somar mais um número?")
      escreva("-> ")
      leia(continuar)

   fimenquanto

   limpatela()

   escreval("Resultado da soma:")
   escreval()
   escreval("   [", soma, " ]   ")
Fimalgoritmo
</code></pre>
<h2>Exercício 2</h2>
<blockquote>
<p>Desenvolva um software em que receba uma quantidade do usuário e imprima na tela essa quantidade de vezes “Programação é nossa melhor matéria!”.</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "ProgramacaoMelhorMateria"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor Cristino
// Descrição   : Imprime uma mensagem N vezes
// Autor(a)    : Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual  : 08/03/2024
Var
   quantidade: inteiro
   contador: inteiro
   certeza: caractere

Inicio
   certeza   &#x3C;- "NÃO"
   quantidade &#x3C;- 0
   contador &#x3C;- 0

   enquanto ((maiusc(certeza) = "NÃO") OU (maiusc(certeza) = "NAO")) faca
      limpatela()

      escreval("Digite o número de vezes")
      escreva("-> ")
      leia(quantidade)

      se (quantidade > 100) entao
         escreval()
         escreval("A mensagem será repedita", quantidade, " vezes!")
         escreval("Você tem certeza que quer continuar?")
         escreva("-> ")
         leia(certeza)
      senao
         certeza &#x3C;- "SIM"
      fimse
   fimenquanto

   limpatela()

   enquanto (contador &#x3C;= quantidade) faca
      contador &#x3C;- contador + 1
      escreval("Programação é a melhor matéria!")
   fimenquanto

Fimalgoritmo
</code></pre>
<h2>Exercício 3</h2>
<blockquote>
<p>Atualize o software do exercício da Lanchonete de modo que o usuário possa fazer um pedido de vários itens no mesmo pedido. Quando ele desejar finalizar o pedido o sistema irá imprimir na tela a lista de produtos comprados e o valor da conta.<br>
Dicas:</p>
<ul>
<li>Trabalhe dentro de um laço de repetição enquanto.</li>
<li>Utilize uma variável do tipo caractere para armazenar os dados do pedido e a cada novo item adicionado, concatene a variável com ela mesma.<br>
Ex: <code>produtos &#x3C;- produtos + " 1 - COXINHA: R$ 6,00 | " {:visualg}</code></li>
</ul>
</blockquote>
<pre><code class="language-visualg">Algoritmo "Cardápio"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor Cristiano
// Descrição   : Cardápio de lanchonete
// Autor(a)    : Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual  : 08/03/2024
Var
   prato:  inteiro
   pedido: caractere
   total:  real
   encerrar: logico
   primeira_iteracao: logico
Inicio
   encerrar &#x3C;- falso
   primeira_iteracao &#x3C;- verdadeiro

   enquanto (nao(encerrar)) faca
      limpatela()

      se(primeira_iteracao) entao
         primeira_iteracao &#x3C;- falso
      senao
         escreval("Quer pedir mais alguma coisa?")
         escreval("Valor total: R$ ", total:2:2)
         escreval()
      fimse

      escreval("------------ PRATOS ------------")
      escreval("[1] Risoto ------------- R$25,00")
      escreval("[2] Espaguete ---------- R$22,00")
      escreval("[3] Strogonoff --------- R$30,00")
      escreval("[4] Macarrão na Chapa -- R$20,00")
      escreval("--------------------------------")
      escreval("[5] ENCERRAR PEDIDO")
      escreval("--------------------------------")
      escreval()
      escreva("-> ")
      leia(prato)

      escolha(prato)
      caso 1
         total &#x3C;- total + 25.00
         pedido &#x3C;- pedido + "Risoto - R$25,00 | "
      caso 2
         total &#x3C;- total + 22.00
         pedido &#x3C;- pedido + "Espaguete - R$22,00 | "
      caso 3
         total &#x3C;- total + 30.00
         pedido &#x3C;- pedido + "Strogonoff - R$30,00 | "
      caso 4
         total &#x3C;- total + 20.00
         pedido &#x3C;- pedido + "Macarrão na Chapa - R$20,00 | "
      caso 5
         encerrar &#x3C;- verdadeiro
      fimescolha
   fimenquanto

   limpatela()

   escreval("-- PEDIDO ------------")
   escreval()
   escreval("| ", pedido)
   escreval()
   escreval("TOTAL: [ R$", total:2:2, " ]")
   escreval()
Fimalgoritmo
</code></pre>
<h1>Aula 6 - VisuAlg</h1>
<p><strong>Data</strong>: 12/03/2024</p>
<h2>Exercício 1</h2>
<blockquote>
<p>Escreva um algoritmo para imprimir os 10 primeiros números inteiros maiores que 100.</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "DezNumerosMaioresQue100"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor
// Descrição   : Imprime os 10 primeiros números inteiros maiores que 100.
// Autor(a)    : Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual  : 19/03/2024

Var
    numero: Inteiro
Inicio
    para numero de 100 ate 110 faca
        escreval(numero)
    fimpara
Fimalgoritmo
</code></pre>
<h2>Exercício 2</h2>
<blockquote>
<p>Escreva um algoritmo que imprima os números pares de 1 a 100. Utilize o sinal de % para verificar o resto da divisão.</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "NumerosParesAte100"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor
// Descrição   : Imprime os números pares de 1 a 100.
// Autor(a)    : Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual  : 19/03/2024

Var
    numero: Inteiro
Inicio
    para numero de 1 ate 100 faca
        se numero % 2 = 0 entao
            escreval(numero)
        fimse
    fimpara
Fimalgoritmo
</code></pre>
<h2>Exercício 3</h2>
<blockquote>
<p>Escreva um algoritmo que pergunte ao usuário quantos números ele quer imprimir na tela. Se o usuário digitar um número maior que 30, interrompa o laço de repetição e imprima na tela uma mensagem para o usuário.</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "NumerosPersonalizados"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor
// Descrição   : Pergunta ao usuário quantos números ele
//               quer imprimir e interrompe se for mais que 30.
// Autor(a)    : Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual  : 19/03/2024

Var
    contador, quantidade: Inteiro

Inicio
    escreval("Quantos números você deseja imprimir?")
    escreva("-> ")
    leia(quantidade)

    para contador de 1 ate quantidade faca
        se quantidade > 30 entao
            escreval("Número muito grande! O máximo permitido é 30.")
            interrompa
        senao
            escreval(contador)
        fimse
    fimpara

Fimalgoritmo
</code></pre>
<h2>Exercício 4</h2>
<blockquote>
<p>Escreva um algoritmo receba um número do usuário e imprima na tela os próximos 10 números múltiplos de 5. Utilize o comando INTERROMPA para sair do loop.</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "ProximosMultiplosDe5"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor
// Descrição   : Imprime os próximos 10 números múltiplos de 5 a partir de um Número fornecido pelo usuário.
// Autor(a)    : Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual  : 19/03/2024

Var
    numero, contador: Inteiro

Inicio
    escreva("Digite um Número: ")
    leia(numero)

    para contador de 1 ate 10 faca
        se numero % 5 = 0 entao
            escreval(numero)
            numero &#x3C;- numero + 5
        senao
            numero &#x3C;- numero + 1
        fimse
    fimpara
Fimalgoritmo
</code></pre>
<h2>Exercício 5</h2>
<blockquote>
<p>Escreva um algoritmo receba do usuário um número, depois receba do usuário uma opção (P para Par ou I para Ímpar) e imprima na tela todos os números de 0 até o número escolhido respeitando a opção escolhida (par ou ímpar). Ex: se o usuário digitar 6 e escolher ímpar, o sistema deve imprimir: <code>1 - 3 - 5</code></p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "ProximosMultiplosDe5"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor
// Descrição   : Imprime os próximos 10 números múltiplos de 5 a partir de um Número fornecido pelo usuário.
// Autor(a)    : Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual  : 19/03/2024

Var
    numero, contador: Inteiro

Inicio
    escreva("Digite um Número: ")
    leia(numero)

    para contador de 1 ate 10 faca
        se numero % 5 = 0 entao
            escreval(numero)
            numero &#x3C;- numero + 5
        senao
            numero &#x3C;- numero + 1
        fimse
    fimpara
Fimalgoritmo
</code></pre>
<h2>Exercício 6</h2>
<blockquote>
<p>Reescreva o código do exercício anterior de modo que a impressão dos números seja escrita em ordem decrescente. Ex: se o usuário digitar 6 e escolher ímpar, o sistema deve imprimir: <code>5 - 3 - 1</code>.</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "NumerosParImparDecrescente"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor
// Descrição   : Imprime números pares ou ímpares em ordem decrescente até o Número escolhido pelo usuário.
// Autor(a)    : Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual  : 19/03/2024

Var
   numero, contador: inteiro
   opcao: caractere

Inicio
   escreva("Digite um Número: ")
   leia(numero)

   escreva("Escolha uma opção (P para Par ou I para ímpar): ")
   leia(opcao)

   para contador de numero ate 0 passo -1 faca
      se (maiusc(opcao) = "P") entao
         se(contador % 2 = 0) entao
            escreval(contador)
         fimse
      senao se (maiusc(opcao) = "I") entao
         se(contador % 2 &#x3C;> 0) entao
            escreval(contador)
         fimse
      fimse
   fimpara

Fimalgoritmo
</code></pre>
<h2>Exercício 7</h2>
<blockquote>
<p>Escreva um algoritmo para pedidos de uma loja de calçados. O algoritmo deve mostrar um menu com ao menos 4 produtos predefinidos e oferecer ao usuário a opção de selecionar mais de um produto ou encerrar o pedido (similar ao exercício do restaurante). Ao final o algoritmo deve mostrar o resumo da compra e o valor total (formatado em reais).</p>
</blockquote>
<pre><code class="language-visualg">Algoritmo "PedidoLojaCalcados"
// Disciplina  : Programação Estruturada
// Professor   : Adjenor
// Descrição   : Sistema de pedidos de uma loja de calçados.
// Autor(a)    : Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
// Data atual  : 19/03/2024

Var
   opcao: caractere
   valor_total: real
Inicio
   valor_total &#x3C;- 0

   repita
      limpatela()
      escreval("MENU DE PRODUTOS:")
      escreval("1 - Tênis Adidas: R$ 199.99")
      escreval("2 - Chinelo Nike: R$ 49.99")
      escreval("3 - Bota Timberland: R$ 299.99")
      escreval("4 - Sandália Havaianas: R$ 29.99")
      escreval("0 - Encerrar pedido")

      escreva("Escolha um produto ou 0 para encerrar: ")
      leia(opcao)

      escolha opcao
      caso "1"
         valor_total &#x3C;- valor_total + 199.99
      caso "2"
         valor_total &#x3C;- valor_total + 49.99
      caso "3"
         valor_total &#x3C;- valor_total + 299.99
      caso "4"
         valor_total &#x3C;- valor_total + 29.99
      fimEscolha
   ate opcao = "0"

   limpatela()

   se valor_total > 0 entao
      escreval("RESUMO DA COMPRA:")
      escreval("Valor total: R$", valor_total:0:2)
   senao
      escreval("Nenhum produto foi selecionado. Pedido cancelado.")
   fimse

Fimalgoritmo
</code></pre>
<h1>Aula 7 - Python</h1>
<p><strong>Data</strong>: 26/03/2024</p>
<h2>Exercício 1</h2>
<blockquote>
<p>Escreva um programa que leia as três notas do aluno e calcule e imprima no console a média que ele obteve na disciplina.</p>
</blockquote>
<pre><code class="language-python">"""
Lê três notas do aluno, calcula e imprime a média no console.

Aluno:     Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Curso:     Gestão da Tecnologia da Informação
Matéria:   Programação Estruturada
Turma:     1º Período - B
Data:      27/03/2024
"""

# Lê as notas do aluno
nota1 = float(input("Digite a primeira nota: "))
nota2 = float(input("Digite a segunda nota: "))
nota3 = float(input("Digite a terceira nota: "))

# Calcula a média
media = (nota1 + nota2 + nota3) / 3

# Imprime a média
print(f"A média do aluno é {media:.2f}")
</code></pre>
<h2>Exercício 2</h2>
<blockquote>
<p>Sabe-se que o m² de construção custa R$850. Escreva um programa que leia as medidas de um terreno retangular e calcula e imprime quanto custa para construir uma casa que ocupe esse terreno.</p>
</blockquote>
<pre><code class="language-python">"""
Programa que lê as medidas de um terreno retangular e calcula e imprime quanto custa
para construir uma casa que ocupe esse terreno. O m² de construção custa R$ 850,00.

Aluno:     Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Curso:     Gestão da Tecnologia da Informação
Matéria:   Programação Estruturada
Turma:     1º Período - B
Data:      27/03/2024
"""

# Lê as medidas do terreno
largura = float(input("Digite a largura do terreno: "))
comprimento = float(input("Digite o comprimento do terreno: "))

# Calcula a área do terreno
area = largura * comprimento

# Calcula o custo da construção
custo = area * 850

# Imprime o custo da construção
print(f"O custo para construir uma casa nesse terreno é R$ {custo:.2f}")
</code></pre>
<h2>Exercício 3</h2>
<blockquote>
<p>Escreva um programa que leia o salário total de uma pessoa e quantas horas ela trabalha por dia. Em seguida, calcule e imprima quanto essa pessoa recebe por hora. Considere o mês com 30 dias.</p>
</blockquote>
<pre><code class="language-python">"""
Programa que lê o salário total de uma pessoa e quantas horas ela trabalha por dia.
Em seguida, calcula e imprime quanto essa pessoa recebe por hora.

Aluno:     Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Curso:     Gestão da Tecnologia da Informação
Matéria:   Programação Estruturada
Turma:     1º Período - B
Data:      27/03/2024
"""

# Lê o salário total
salario = float(input("Digite o salário total\n-> "))

# Lê a quantidade de horas trabalhadas por dia
horas_por_dia = float(input("Digite a quantidade de horas trabalhadas por dia\n-> "))

# Calcula horas trabalhadas no mês
horas_por_mes = horas_por_dia * 30

# Calcula o valor da hora
valor_hora = salario / horas_por_mes

# Imprime o valor da hora
print(f"\nO valor da hora é R$ {valor_hora:.2f}")
</code></pre>
<h2>Exercício 4</h2>
<blockquote>
<p>Escreva um programa que peça ao usuário para informar o peso e a altura com o comando leia, depois calcule e imprima na tela o IMC dessa pessoa sabendo que a fórmula do IMC é (peso/altura²).</p>
</blockquote>
<pre><code class="language-python">"""
Programa que pede ao usuário para informar o peso e a altura com o comando leia, depois
calcula e imprime na tela o IMC dessa pessoa sabendo que a fórmula do IMC é (peso/altura²).

Aluno:     Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Curso:     Gestão da Tecnologia da Informação
Matéria:   Programação Estruturada
Turma:     1º Período - B
Data:      27/03/2024
"""

# Lê o peso
peso = float(input("Digite o peso (kg)\n-> "))

# Lê a altura
altura_cm = float(input("Digite a altura (cm)\n-> "))

# Calcula o IMC
imc = peso / (altura_cm/100) ** 2

# Imprime o IMC
print(f"\nO IMC é {imc:.2f}")
</code></pre>
<h1>Aula 8 - Python</h1>
<p><strong>Data</strong>: 02/04/2024</p>
<h2>Exercício 1</h2>
<blockquote>
<p>Desenvolva um software que receba uma string do usuário e depois solicite a ele quantas letras da string ele quer que sejam separadas, depois imprima na tela as duas partes da string.<br>
EX: se o usuário digitar “Faculdade” e o número 5, o software deve retornar:<br>
Primeira Parte: “Facul”<br>
Segunda Parta: “dade”</p>
</blockquote>
<pre><code class="language-python">class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKCYAN = '\033[96m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

text = input("Texto a ser dividido: ")
position = input("Posição de divisão da string: ")

if not text or not position:
    print(f"\n{bcolors.FAIL}Quantidade de parâmetros insuficientes ou inválidos!{bcolors.ENDC}")
    quit()

position = int(position)

if position > len(text):
    print(f"\n{bcolors.FAIL}Posição de divisão maior que o tamanho do texto!{bcolors.ENDC}")
    print(f"Tamanho do texto: {bcolors.BOLD}{len(text)}{bcolors.ENDC}")
    print(f"Posição de divisão: {bcolors.BOLD}{position}{bcolors.ENDC}")
    quit()

first_part, second_part = text[:position], text[position:]

print(f"\n{bcolors.OKGREEN}Primeira parte:{bcolors.ENDC} {bcolors.BOLD}{first_part}{bcolors.ENDC}")
print(f"{bcolors.OKGREEN}Segunda parte:{bcolors.ENDC}  {bcolors.BOLD}{second_part}{bcolors.ENDC}")
</code></pre>
<h2>Exercício 2</h2>
<blockquote>
<p>Desenvolva um software que receba do usuário seu nome, seu sobrenome e uma quantidade. Depois solicite a ele quantas vezes ele deseja imprimir o conjunto (nome e sobrenome) e imprima na tela essa quantidade de vezes. Utilize <code>\n</code> para quebra de linha.</p>
</blockquote>
<pre><code class="language-python">from os import system, name

nome = input("Digite seu nome: ")
sobrenome = input("Digite seu sobrenome: ")
n = int(input("Número de repetições: "))

# limpa terminal
if name == 'nt':
    # windows
    system('cls')
else:
    # outros unix (linux, mac...)
    system('clear')

for i in range(n):
    print(f"{nome} {sobrenome}")
</code></pre>
<h2>Exercício 3</h2>
<blockquote>
<p>Desenvolva um software que receba do usuário um valor e imprima na tela este valor formatado para reais (R$) utilizando composição.</p>
</blockquote>
<pre><code class="language-python">valor = float(input('Digite o valor: '))
print("R$ %.2f"%valor)
</code></pre>
<h2>Exercício 4</h2>
<blockquote>
<p>Desenvolva um software que receba do usuário um valor de compra, depois receba um valor em dinheiro e calcule o troco e imprima na tela este valor formatado para reais (R$) utilizando composição.</p>
</blockquote>
<pre><code class="language-python">valor_compra = float(input('Digite o valor da compra: '))
valor_pago = float(input('Digite o valor pago: '))

troco = valor_pago - valor_compra

if troco &#x3C; 0:
    print('\nValor pago insuficiente, falta R$ %.2f.'%abs(troco))
else:
    print('\nTroco: R$ %.2f'%troco)
</code></pre>
<h1>Aula 9 - Python</h1>
<p><strong>Data</strong>: 09/04/2024</p>
<h2>Exercício 1</h2>
<blockquote>
<p>Desenvolva um software que leia dois números e que pergunte qual operação você deseja realizar. Você deve poder calcular a soma (<code>+</code>), subtração (<code>-</code>), multiplicação (<code>*</code>) e divisão (<code>/</code>). Exiba o resultado da operação solicitada.</p>
</blockquote>
<pre><code class="language-python">"""
Nome:      Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Data:      10/04/2024
Matéria:   Programação Estruturada
Turma:     1º Perí. B
"""

# lê dois números e uma operação
num1 = float(input("Digite o primeiro número: "))
num2 = float(input("Digite o segundo número: "))
operacao = input("Digite a operação [+|-|*|/]: ")

# exiba o resultado da operação solicidada
if operacao == "+":
    print(f"O resultado da soma é: {num1 + num2}")
elif operacao == "-":
    print(f"O resultado da subtração é: {num1 - num2}")
elif operacao == "*":
    print(f"O resultado da multiplicação é: {num1 * num2}")
elif operacao == "/":
    # 0 não pode ser dividido
    if num2 == 0:
        print("Não é possível dividir por zero.")
    else:
        print(f"O resultado da divisão é: {num1 / num2}")
else:
    print("Operação inválida.")
</code></pre>
<h2>Exercício 2</h2>
<blockquote>
<p>Desenvolva um software para aprovar o empréstimo bancário para compra de uma casa. O programa deve perguntar o valor da casa a comprar, o salário e a quantidade de anos a pagar. O valor da prestação mensal não pode ser superior a 30% do salário. Calcule o valor da prestação como sendo o valor da casa a comprar dividido pelo número de meses a pagar.</p>
</blockquote>
<pre><code class="language-python">"""
Nome:      Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Data:      10/04/2024
Matéria:   Programação Estruturada
Turma:     1º Perí. B
"""

valor_casa = float(input("Digite o valor da casa: R$ ").strip().replace(",", "."))
salario = float(input("Digite o salário: R$ ").strip().replace(",", "."))
anos = int(input("Digite a quantidade de anos a pagar: "))

meses = anos * 12

prestacao = valor_casa / meses

if prestacao > (salario * 0.3):
    print("Empréstimo negado.")
else:
    print(f"Empréstimo aprovado. A prestação será de R$ {prestacao:.2f}.")
</code></pre>
<h2>Exercício 3</h2>
<blockquote>
<p>Desenvolva um software de lanchonete que apresente para o cliente um menu com ao menos 4 opções de salgado para que ele escolha, depois apresente ao menos 4 opções de bebidas. Ao final, o software deve mostrar na tela o valor total da compra e os itens comprados.</p>
</blockquote>
<pre><code class="language-python">"""
Nome:      Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Data:      10/04/2024
Matéria:   Programação Estruturada
Turma:     1º Perí. B
"""

# menu com 4 opções de salgados
print("+------ MENU SALGADOS -------+")
print("| [1] Coxinha ------ R$ 3,50 |")
print("| [2] Pastel ------- R$ 4,00 |")
print("| [3] Empada ------- R$ 3,00 |")
print("| [4] Enroladinho -- R$ 2,50 |")
print("+----------------------------+")
salgado = int(input("-> "))

if salgado &#x3C; 1 or salgado > 4:
    print("Opção inválida.")
    exit()

# menu com 4 opções de bebidas
print("\n+------ MENU BEBIDAS --------+")
print("| [1] Refrigerante - R$ 3,00 |")
print("| [2] Suco --------- R$ 2,50 |")
print("| [3] Água --------- R$ 2,00 |")
print("| [4] Chá ---------- R$ 2,50 |")
print("+----------------------------+")
bebida = int(input("-> "))

if bebida &#x3C; 1 or bebida > 4:
    print("Opção inválida.")
    exit()

# cálculo do valor total
total = 0

if salgado == 1:
    total += 3.50
elif salgado == 2:
    total += 4.00
elif salgado == 3:
    total += 3.00
elif salgado == 4:
    total += 2.50

if bebida == 1:
    total += 3.00
elif bebida == 2:
    total += 2.50
elif bebida == 3:
    total += 2.00
elif bebida == 4:
    total += 2.50

print("\nTotal a pagar: R$ %.2f" % total)
</code></pre>
<h2>Exercício 4</h2>
<blockquote>
<p>Desenvolva um software para analisar se um aluno foi aprovado. O software deve receber 4 notas (entre 0 e 25) e ao final atestar as seguintes possibilidades:</p>
<ul>
<li>Se o total for maior ou igual 80 - ALUNO APROVADO - EXCELENTE</li>
<li>Se o total for entre 60 e 79 - ALUNO APROVADO</li>
<li>Se o total for entre 40 e 59 - ALUNO EM RECUPERAÇÃO</li>
<li>Se o total for menor que 40 - ALUNO REPROVADO</li>
<li>Se alguma das notas estiver fora do intervalo (entre 0 e 25) o software deve exibir a mensagem de “Valor inválido” e encerrar.</li>
</ul>
</blockquote>
<pre><code class="language-python">"""
Nome:      Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Data:      11/04/2024
Matéria:   Programação Estruturada
Turma:     1º Perí. B
"""

nota1 = float(input("Nota 1: "))
nota2 = float(input("Nota 2: "))
nota3 = float(input("Nota 3: "))
nota4 = float(input("Nota 4: "))

if nota1 &#x3C; 0 or nota1 > 25:
    print("Valor inválido.")
    exit()
elif nota2 &#x3C; 0 or nota2 > 25:
    print("Valor inválido.")
    exit()
elif nota3 &#x3C; 0 or nota3 > 25:
    print("Valor inválido.")
    exit()
elif nota4 &#x3C; 0 or nota4 > 25:
    print("Valor inválido.")
    exit()

total = nota1 + nota2 + nota3 + nota4

if total >= 80:
    print("ALUNO APROVADO - EXCELENTE")
elif total >= 60:
    print("ALUNO APROVADO")
elif total >= 40:
    print("ALUNO EM RECUPERAÇÃO")
else:
    print("ALUNO REPROVADO")
</code></pre>
<h2>Exercício 5</h2>
<blockquote>
<p>Escreva um programa que calcule o preço pelo fornecimento de energia elétrica. Pergunte a quantidade de kWh consumidos e o tipo de instalação: R para residências, I para indústrias e C para comércios. Calcule o preço a pagar de acordo com a tabela a seguir:</p>
<ul>
<li>Residências:
<ul>
<li>Até 500 kWh: R$ 0,40</li>
<li>Acima de 500 kWh: R$ 0,65</li>
</ul>
</li>
<li>Comércios:
<ul>
<li>Até 1000 kWh: R$ 0,55</li>
<li>Acima de 1000 kWh: R$ 0,60</li>
</ul>
</li>
<li>Indústrias:
<ul>
<li>Até 5000 kWh: R$ 0,55</li>
<li>Acima de 5000 kWh: R$ 0,60</li>
</ul>
</li>
</ul>
</blockquote>
<pre><code class="language-python">"""
Nome:      Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Data:      11/04/2024
Matéria:   Programação Estruturada
Turma:     1º Perí. B
"""

kwh = int(input("Quantidade de kWh consumido: "))

print("\n+- TIPO DE INSTALAÇÃO -+")
print("|  [R] Residencial     |")
print("|  [C] Comercial       |")
print("|  [I] Industrial      |")
print("+----------------------+")
instalacao = input("-> ").upper()

total = 0
if instalacao == "R":
    if kwh &#x3C;= 500:
        total = kwh * 0.40
    else:
        total = kwh * 0.65
elif instalacao == "C":
    if kwh &#x3C;= 1000:
        total = kwh * 0.55
    else:
        total = kwh * 0.60
elif instalacao == "I":
    if kwh &#x3C;= 5000:
        total = kwh * 0.55
    else:
        total = kwh * 0.60
else:
    print("Tipo de instalação inválido.")
    exit()

print("\nTotal a pagar: R$ %.2f" % total)
</code></pre>
<h1>Aula 10 - Python</h1>
<p><strong>Data</strong>: 16/04/2024</p>
<h2>Exercício 1</h2>
<blockquote>
<p>Desenvolva um software que receba do usuário uma quantidade e imprima na tela todos os números pares de 0 até o número digitado.</p>
</blockquote>
<pre><code class="language-python">"""
Nome:      Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Data:      21/04/2024
Matéria:   Programação Estruturada
Turma:     1º Perí. B
"""

limite = int(input("Digite um número\n-> "))

for n in range(0, limite+1, 2):
  print(n)
</code></pre>
<h2>Exercício 2</h2>
<blockquote>
<p>Altere o software do exercício anterior para que o sistema receba também um tipo (P para Pares e I para Impares) e imprima apenas os números de acordo com a escolha.</p>
</blockquote>
<pre><code class="language-python">"""
Nome:      Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Data:      21/04/2024
Matéria:   Programação Estruturada
Turma:     1º Perí. B
"""

limite = int(input("Digite um número\n-> "))
opcao = input("\nOpção | [P]ar ou [I]mpar\n-> ").upper()

print()

if opcao == "P":
  for i in range(0, limite+1, 2):
    print(i)
elif opcao == "I":
  for i in range(1, limite+1, 2):
    print(i)
</code></pre>
<h2>Exercício 3</h2>
<blockquote>
<p>Valide a opção digitada, caso o usuário digite um valor diferente se P ou I, solicite a ele que digite novamente. DICA: Utilize repetições aninhadas.</p>
</blockquote>
<pre><code class="language-python">"""
Nome:      Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Data:      21/04/2024
Matéria:   Programação Estruturada
Turma:     1º Perí. B
"""

limite = int(input("Digite um número\n-> "))

opcoes_validas = ["P", "I"]
opcao = ""
while opcao not in opcoes_validas:
  opcao = input("\nOpção | [P]ar ou [I]mpar\n-> ").upper()

  if opcao not in opcoes_validas:
    print("Opção inválida. Tente novamente.")

print()

if opcao == "P":
  for i in range(0, limite+1, 2):
    print(i)
elif opcao == "I":
  for i in range(1, limite+1, 2):
    print(i)
</code></pre>
<h2>Exercício 4</h2>
<blockquote>
<p>Escreva um programa que leia um número e verifique se é ou não um número primo. Para fazer essa verificação, calcule o resto da divisão do número por 2 e depois por todos os números ímpares até o número lido. Se o resto de uma dessas divisões for igual a zero, o número não é primo. Observe que 0 e 1 não são primos e que 2 é o único número primo que é par.</p>
</blockquote>
<pre><code class="language-python">import sys

"""
Nome:      Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Data:      21/04/2024
Matéria:   Programação Estruturada
Turma:     1º Perí. B
"""

def e_primo(primo: bool = True):
  if primo:
    print(f"{numero} é primo.")
  else:
    print(f"{numero} não é primo.")

  sys.exit()

numero = int(input("Digite um número\n-> "))

if numero &#x3C; 2:
  e_primo(primo=False)

primo = True
for i in range(2, numero):
  if numero % i == 0:
    primo = False
    break

e_primo(primo)


</code></pre>
<h2>Exercício 5</h2>
<blockquote>
<p>Desenvolva um software de restaurante que apresente ao menos 4 tipos de produtos e a opção de finalizar o pedido. O software deve perguntar ao usuário se ele deseja adicionar outro produto Ao final ele deve mostrar na tela todos os produtos que o cliente comprou e o total do pedido.<br>
<strong>DICA</strong>: Utilize uma variável String para armazenar os produtos escolhidos e uma variável float para armazenar o total do pedido. Apresente o total formatado para Real.</p>
</blockquote>
<pre><code class="language-python">"""
Nome:      Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Data:      21/04/2024
Matéria:   Programação Estruturada
Turma:     1º Perí. B
"""

total = 0.0
pedidos = []

while True:
  print("\n+" + " Cardápio ".center(31, "-") + "+")
  print("| [1] Hambúrguer ----- R$ 10.00 |")
  print("| [2] Pizza ---------- R$ 20.00 |")
  print("| [3] Refrigerante --- R$ 5.00  |")
  print("| [4] Batata Frita --- R$ 8.00  |")
  print("| [5] FINALIZAR PEDIDO          |")
  print("+" + "".center(31, "-") + "+")
  escolha = int(input("Escolha uma opção\n-> "))

  if escolha == 1:
    total += 10.00
    pedidos.append("Hambúrguer")
  elif escolha == 2:
    total += 20.00
    pedidos.append("Pizza")
  elif escolha == 3:
    total += 5.00
    pedidos.append("Refrigerante")
  elif escolha == 4:
    total += 8.00
    pedidos.append("Batata Frita")
  elif escolha == 5:
    break

print("\n" + "+" + " Pedido ".center(31, "-") + "+")

for pedido in pedidos:
  print(f"| {pedido} ".ljust(32, " ") + "|")

print("+" + "".center(31, "-") + "+")
print(f"| Total: R$ {total:.2f} ".ljust(32, " ") + "|")
print("+" + "".center(31, "-") + "+")

</code></pre>
<h1>Aula 11 - Python</h1>
<p><strong>Data</strong>: 23/04/2024</p>
<h2>Exercício 1</h2>
<blockquote>
<p>Altere o software do Exemplo I de modo que ele agora receba as notas do usuário e calcule a média e mostre na tela um resumo das notas.<br>
<strong>DICA</strong>: inicie a lista de notas zerada: <code>notas=[0,0,0,0,0] {:python}</code></p>
<p>Utilize duas estruturas <code>while {:python}</code></p>
</blockquote>
<pre><code class="language-python">"""
Nome:      Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Data:      29/04/2024
Matéria:   Programação Estruturada
Turma:     1º Perí. B
"""

notas = [0,0,0,0,0]

indice = 0
while indice &#x3C; 5:
    notas[indice] = int(input('Nota %d: ' % (indice + 1)))
    indice += 1

soma = 0
x = 0

while x &#x3C; 5:
    soma += notas[x]
    x += 1

print()

print("*"*22)
print("*", "RESUMO DAS NOTAS".center(18), "*")
print("*"*22)

print()


indice = 0
while indice &#x3C; 5:
    print('Nota %d: %d' % (indice + 1, notas[indice]))
    indice += 1

print('Média: %5.2f' % (soma / x))
</code></pre>
<h2>Exercício 2</h2>
<blockquote>
<p>Altere o software do restaurante desenvolvido na semana passada de modo que a cada interação o software mostrará para o cliente todos os produtos comprados e o total da compra. O software deve permitir a ele que ele remova produtos ou adicione mais produtos.<br>
<strong>DICA</strong>: Utilize ao menos duas listas, uma para os produtos e outra para os valores.</p>
</blockquote>
<pre><code class="language-python">"""
Nome:      Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Data:      29/04/2024
Matéria:   Programação Estruturada
Turma:     1º Perí. B
"""

pratos = [
  "Hambúrguer",
  "Pizza",
  "Refrigerante",
  "Batata Frita"
]

valores = [
  10.00,
  20.00,
  5.00,
  8.00
]

total = 0.0
pedido = []

while True:
  print("\n+" + " Menu ".center(22, "-") + "+")
  print("| [1] Adicionar prato  |")
  print("| [2] Remover prato    |")
  print("| [3] FINALIZAR PEDIDO |")
  print("+" + "-"*22 + "+")
  escolha = int(input("Escolha uma opção\n-> "))

  if escolha == 1:
    # ADICIONAR PEDIDO

    print("\n+" + " Cardápio ".center(28, "-") + "+")

    indice = 0
    while indice &#x3C; len(pratos):
      opcao = f"[{indice + 1}] {pratos[indice]} - R$ {valores[indice]:.2f}"
      print("|", opcao.ljust(26, " "), "|")
      indice += 1

    print("+" + "".center(28, "-") + "+")
    prato = int(input("Escolha um prato\n-> ")) - 1
    total += valores[prato]
    pedido.append(pratos[prato]) # adiciona um elemeto à lista

  elif escolha == 2:
    # REMOVER PEDIDO

    print("\n+" + " Pedidos ".center(28, "-") + "+")

    indice = 0
    while indice &#x3C; len(pedido):
      opcao = f"[{indice + 1}] {pedido[indice]}"
      print("|", opcao.ljust(26, " "), "|")
      indice += 1

    print("+" + "".center(28, "-") + "+")

    prato = int(input("Escolha um prato para remover\n-> ")) - 1
    total -= valores[prato]
    del pedido[prato] # OU pedido.pop(prato) # remove um elemento da lista

  elif escolha == 3:
    break
  else:
    print("Opção inválida")


# resulmo do pedido e valor total
print("\n+" + " Pedido ".center(25, "-") + "+")

indice = 0
while indice &#x3C; len(pedido):
  print(f"| {pedido[indice]} ".ljust(26, " ") + "|")
  indice += 1

# exibe o valor total antes de encerrar o quadro
print("+" + "".center(25, "-") + "+")
print(f"| Total: R$ {total:.2f} ".ljust(26, " ") + "|")
print("+" + "".center(25, "-") + "+")
</code></pre>
<h2>Exercício 3</h2>
<blockquote>
<p>Faça um programa que leia duas listas e que gere uma terceira com os elementos das duas primeiras.</p>
</blockquote>
<pre><code class="language-python">"""
Nome:      Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Data:      29/04/2024
Matéria:   Programação Estruturada
Turma:     1º Perí. B
"""

L1 = [7,5,3]
L2 = [4,6,8]

resultado = L1[:] + L2[:]

print(L1) # [7, 5, 3]
print(L2) # [4, 6, 8]
print(resultado) # [7, 5, 3, 4, 6, 8]
</code></pre>
<h2>Exercício 4</h2>
<blockquote>
<p>Faça um programa que percorra duas listas e gere uma terceira sem elementos repetidos.</p>
</blockquote>
<pre><code class="language-python">"""
Nome:      Mateus Felipe Gonçalves &#x3C;contato@mateusf.com>
Professor: Adjenor Cristiano
Data:      29/04/2024
Matéria:   Programação Estruturada
Turma:     1º Perí. B
"""

L1 = [7,5,3,1,2,9]
L2 = [1,4,9,8,3,6]

resultado = list(set(L1 + L2))

print(L1) # [7, 5, 3, 1, 2, 9]
print(L2) # [1, 4, 9, 8, 3, 6]
print(resultado) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
</code></pre>
<h1>Aula 12 - Python</h1>
<h1>Aula 13 - Python</h1>
<p><strong>Data</strong>: 14/05/2024</p>
<h2>Exercício 1</h2>
<blockquote>
<p>Altere o programa anterior de modo que ele receba os valores para preencher a lista, a cada valor digitado o sistema ofereça ao usuário a opção de imprimir a lista com seus índices ([0] - 4). O programa também deve oferecer ao usuário a opção de adicionar mais um valor ou excluir um valor. Ao finalizar o sistema deve apresentar na tela todos os números digitados, o maior, menor e a média.</p>
</blockquote>
<pre><code class="language-python"># verificação do maior valor
lista = []


while True:
    novo_valor = int(input("Digite um valor: "))
    lista.append(novo_valor)
    print("")

    exibir = input("Deseja exibir a lista? (s/n)")

    if exibir == "s":
        print(f"(I) N")
        for cont, item in enumerate(lista):
            print(f"({cont}) {item}")

    print("Escolha uma opção:")
    print("[1]> Adicionar novo valor")
    print("[2]> Excluir valor")
    print("[3]> Finalizar")
    escolha = int(input("-> "))

    print("")
    if escolha == 1:
        continue
    elif escolha == 2:
        print(f"(I) N")
        for cont, item in enumerate(lista):
            print(f"({cont}) {item}")
        excluir = int(input("Digite o índice do valor que deseja excluir: "))
        del lista[excluir]
    elif escolha == 3:
        break


maior = 0
menor = 0
soma = 0

for cont, item in enumerate(lista):
    if (item > maior) or cont == 0:
        maior = item

for cont, item in enumerate(lista):
    if (item &#x3C; menor) or cont == 0:
        menor = item

for item in lista:
    soma += item


for cont, item in enumerate(lista):
    print(f"({cont}) {item}")

print(f"O maior valor é: {maior}")
print(f"O menor valor é: {menor}")
print(f"A média dos valores é: {soma / len(lista)}")
</code></pre>
<h2>Exercício 2</h2>
<blockquote>
<p>Desenvolva um programa para separar os valores da lista [9,8,7,12,0,13,21,35,6,11,1] em duas listas, uma com os pares e outra com os ímpares.</p>
</blockquote>
<pre><code class="language-python">lista = [9,8,7,12,0,13,21,35,6,11,1]

pares = []
impares = []

for item in lista:
    if item % 2 == 0:
        pares.append(item)
    else:
        impares.append(item)

print(f"Pares: {pares}")
print(f"Ímpares: {impares}")
</code></pre>
<h2>Exercício 3</h2>
<blockquote>
<p>Altere o software do exercício anterior de forma que ele receba os dados do usuário para criar na lista de compras. O sistema deve oferecer ao usuário a possibilidade de exibir a lista de compras, adicionar e remover itens, além de mostrar os totais (valor total da compra e quantidade total de ítens).</p>
</blockquote>
<pre><code class="language-python">import os
from time import sleep

limpar = lambda: os.system("clear")

itens = []

while True:
    limpar()
    print("+-- MENU PRINCIPAL --+")
    print("| [1] Adicionar item |")
    print("| [2] Remover item   |")
    print("| [3] Listar itens   |")
    print("| [4] Sair           |")
    print("+--------------------+")
    opcao = input("-> ")

    if not opcao.isdigit():
        print("\nOpção inválida!")
        sleep(2)
        continue

    opcao = int(opcao)

    if opcao == 1:
        limpar()

        print("[ ADICIONAR ITEM ]\n")

        nome = input("Nome do item: ")
        quantidade = int(input("Quantidade: "))
        valor_unitario = float(input("Valor unitário: ").replace(",", "."))

        itens.append([nome, quantidade, valor_unitario])

        print("\nItem adicionado com sucesso!")
        sleep(2)
    elif opcao == 2:
        limpar()

        if len(itens) == 0:
            print("Nenhum item para remover!")
            sleep(2)
            continue

        print("[ REMOVER ITEM ]\n")

        print("[ID] Nome\n")
        for indice, item in enumerate(itens):
            print("[%d] %s" % (indice, item[0]))

        print("\nID do ítem que deseja remover")
        id_item = int(input("-> "))

        if id_item &#x3C; 0 or id_item >= len(itens):
            print("\nID inválido!")
            sleep(2)
            continue
        else:
            del itens[id_item]
            print("\nItem removido com sucesso!")
            sleep(2)
    elif opcao == 3:
        limpar()

        print("[ ITENS ]\n")

        quantidade_total = 0
        valor_total = 0

        print("ID | Nome - Quantidade - Valor unitário (Valor total)")
        print("---|-----------------------------------------------")
        for indice, item in enumerate(itens):
            print("%d  | %s - %d unidade(s) - R$ %.2f (R$ %.2f)" % (indice, item[0], item[1], item[2], item[1] * item[2]))
            quantidade_total += item[1]
            valor_total += item[1] * item[2]

        print("\nQuantidade unitária de itens -- %d" % len(itens))
        print("Quantidade total de itens ----- %d" % quantidade_total)
        print("Valor total da compra --------- R$ %.2f" % valor_total)

        input("\nPressione enter para continuar...")
    elif opcao == 4:
        limpar()
        break
    else:
        print("\nOpção inválida!")
        sleep(2)
</code></pre>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>fapam</category>
            <category>gti</category>
            <category>exercícios</category>
            <category>curso</category>
            <category>faculdade</category>
            <category>university</category>
            <category>programming</category>
            <category>visualg</category>
            <category>portugol</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/exercicios-gti-p1-programacao-estruturada/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Why use functional `setState`]]></title>
            <link>https://mateusf.com/blog/post/why-use-functional-setstate</link>
            <guid>why-use-functional-setstate</guid>
            <pubDate>Wed, 24 Jan 2024 12:34:39 GMT</pubDate>
            <description><![CDATA[Advantage of function on `setState` over variable]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/why-use-functional-setstate/thumbnail" alt=""> <br>
This post is a resume of post <a href="https://www.linkedin.com/pulse/choosing-right-state-update-method-normal-vs-updates-react-verma-/">Choosing the Right State Update Method Normal vs. Functional State Updates in React</a>, by <a href="https://www.linkedin.com/in/apoorveverma/?lipi=urn%3Ali%3Apage%3Ad_flagship3_pulse_read%3BudVa6%2FuETiu9EDMDaWJFkA%3D%3D">Apoorve Verma</a>.<br>
</p>
<h1>Diferences between <code>setState</code> methods</h1>
<p>Before all, let's see the difference between the state update methods treated here.</p>
<h2>Normal States Updates</h2>
<pre><code class="language-tsx">import React, { useState } from 'react'

const Counter = () => {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount(count + 1);
  };

  return (
    &#x3C;div>
      &#x3C;p>Count: {count}&#x3C;/p>
      &#x3C;button onClick={increment}>Increment&#x3C;/button>
    &#x3C;/div>
  );
};

export default Counter;
</code></pre>
<h2>Functional State Updates</h2>
<pre><code class="language-tsx">import React, { useState } from 'react'

const Counter = () => {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount((prevCount) => prevCount + 1);
  };

  return (
    &#x3C;div>
      &#x3C;p>Count: {count}&#x3C;/p>
      &#x3C;button onClick={increment}>Increment&#x3C;/button>
    &#x3C;/div>
  );
};

export default Counter;
</code></pre>
<h1>When use functional state updates</h1>
<p>The need for <strong>functional state updates</strong> arises from the <strong>problem of stale state</strong> and ensuring accurate state transitions. In <strong>normal state updates</strong>, subsequent state updates are based on the previous state value. However, when dealing with asynchronous updates or multiple state updates within a single function or event handler, the current state may not be up to date. This can lead to inconsistencies and unexpected behavior in your application.</p>
<h2>Problem</h2>
<p>I.e., suppose you have a component that increments the count by 10 three times when a button is clicked:</p>
<pre><code class="language-tsx">import React, { useState } from 'react'

const Counter = () => {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount(count + 10);
    setCount(count + 10);
    setCount(count + 10);
  };

  return (
    &#x3C;div>
      &#x3C;p>Count: {count}&#x3C;/p>
      &#x3C;button onClick={increment}>Increment&#x3C;/button>
    &#x3C;/div>
  );
};

export default Counter;
</code></pre>
<p>In this case, you might expect the count to increase by 30 after three button clicks. However, due to the nature of normal state updates, the value of count will only increase by 10, as each setCount call operates on the stale value of count.</p>
<p><img src="assets/screencast1.gif" alt="Screencast on repository: content/posts/why-use-functional-setstate/assets/screencast1.gif"></p>
<h2>Solution</h2>
<p>Functional state updates solve this problem by <strong>providing the previous state value</strong> as an argument within the updater function.<br>
To fix the example above using functional state updates, you can modify the increment function as follows:</p>
<pre><code class="language-tsx">const increment = () => {
  setCount((prevCount) => prevCount + 10);
  setCount((prevCount) => prevCount + 10);
  setCount((prevCount) => prevCount + 10);
};
</code></pre>
<p><img src="assets/screencast2.gif" alt="Screencast on repository: content/posts/why-use-functional-setstate/assets/screencast2.gif"></p>
<h1>Referencies</h1>
<p>Updating state based on the previous state (<strong>oficial React docs</strong>): <em><a href="https://react.dev/reference/react/useState#updating-state-based-on-the-previous-state">https://react.dev/reference/react/useState#updating-state-based-on-the-previous-state</a></em></p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>react</category>
            <category>usestate</category>
            <category>hook</category>
            <category>states</category>
            <category>lifecycle</category>
            <category>programming</category>
            <category>code</category>
            <category>pattern</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/why-use-functional-setstate/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Raiz de 2 é inrracional]]></title>
            <link>https://mateusf.com/blog/post/raiz-de-2-e-inrracional</link>
            <guid>raiz-de-2-e-inrracional</guid>
            <pubDate>Sun, 15 Oct 2023 20:55:36 GMT</pubDate>
            <description><![CDATA[Prova de que raiz de 2 é inrracional]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/raiz-de-2-e-inrracional/thumbnail" alt=""> # Definições</p>
<p>Primeiro recordamos que <em>números pares</em> são os inteiros <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>±</mo><mn>2</mn><mo separator="true">,</mo><mo>±</mo><mn>4</mn><mo separator="true">,</mo><mo>±</mo><mn>6</mn><mo separator="true">,</mo><mo>±</mo><mn>8</mn><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">\pm2, \pm4, \pm6, \pm8,...</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord">±</span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">±</span><span class="mord">4</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">±</span><span class="mord">6</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">±</span><span class="mord">8</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">...</span></span></span></span>, que podem ser escritos na forma <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><mi>n</mi></mrow><annotation encoding="application/x-tex">2n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span><span class="mord mathnormal">n</span></span></span></span> para algum inteiro <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span>. Um número <em>ímpar</em> é um inteiro como <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>±</mo><mn>1</mn><mo separator="true">,</mo><mo>±</mo><mn>3</mn><mo separator="true">,</mo><mo>±</mo><mn>5</mn><mo separator="true">,</mo><mo>±</mo><mn>7</mn><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">\pm1, \pm3, \pm5, \pm7,...</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord">±</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">±</span><span class="mord">3</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">±</span><span class="mord">5</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">±</span><span class="mord">7</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">...</span></span></span></span>, que pode ser escrito na forma <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><mi>n</mi><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">2n+1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7278em;vertical-align:-0.0833em;"></span><span class="mord">2</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span> para algum inteiro <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span>. Então <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>6</mn><mo>=</mo><mn>2</mn><mo>⋅</mo><mn>3</mn></mrow><annotation encoding="application/x-tex">6=2\cdot3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">6</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">3</span></span></span></span> é par (escolhemos <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>3</mn></mrow><annotation encoding="application/x-tex">n=3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">3</span></span></span></span>) e <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>11</mn><mo>=</mo><mn>2</mn><mo>⋅</mo><mn>5</mn><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">11=2\cdot5+1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">11</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.7278em;vertical-align:-0.0833em;"></span><span class="mord">5</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span> é ímpar (escolhemos <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>5</mn></mrow><annotation encoding="application/x-tex">n=5</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">5</span></span></span></span>).</p>
<p>Observamos que o quadrado de um número par é par. Com efeito, se <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> é um inteiro e <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><mi>n</mi></mrow><annotation encoding="application/x-tex">2n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span><span class="mord mathnormal">n</span></span></span></span> é um número par, então</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">(</mo><mn>2</mn><mi>n</mi><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>=</mo><mn>4</mn><msup><mi>n</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">(2n)^2=4n^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.1141em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">2</span><span class="mord mathnormal">n</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8641em;"></span><span class="mord">4</span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span>
<p>é um número par, que pode ser escrito <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><mo stretchy="false">(</mo><mn>2</mn><msup><mi>n</mi><mn>2</mn></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">2(2n²)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0641em;vertical-align:-0.25em;"></span><span class="mord">2</span><span class="mopen">(</span><span class="mord">2</span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>, o produto de <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn></mrow><annotation encoding="application/x-tex">2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span></span></span></span> pelo inteiro <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><msup><mi>n</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">2n²</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">2</span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span>.</p>
<p>O quadrado de um número ímpar é ímpar. Para provar isso, seja <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><mi>n</mi><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">2n+1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7278em;vertical-align:-0.0833em;"></span><span class="mord">2</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span> um número ímpar (<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> sendo um inteiro). Então seu quadrado é</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">(</mo><mn>2</mn><mi>n</mi><mo>+</mo><mn>1</mn><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>=</mo><mn>4</mn><msup><mi>n</mi><mn>2</mn></msup><mo>+</mo><mn>4</mn><mi>n</mi><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">(2n+1)²=4n²+4n+1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">2</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1.1141em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.9474em;vertical-align:-0.0833em;"></span><span class="mord">4</span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.7278em;vertical-align:-0.0833em;"></span><span class="mord">4</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span></span>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mspace width="5.5em"></mspace><mo>=</mo><mn>2</mn><mo stretchy="false">(</mo><mn>2</mn><msup><mi>n</mi><mn>2</mn></msup><mo>+</mo><mn>2</mn><mi>n</mi><mo stretchy="false">)</mo><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">\hspace{5.5em} =2(2n²+2n)+1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.3669em;"></span><span class="mspace" style="margin-right:5.5em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.1141em;vertical-align:-0.25em;"></span><span class="mord">2</span><span class="mopen">(</span><span class="mord">2</span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">2</span><span class="mord mathnormal">n</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span></span>
<p>Como <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><msup><mi>n</mi><mn>2</mn></msup><mo>+</mo><mn>2</mn><mi>n</mi></mrow><annotation encoding="application/x-tex">2n²+2n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8974em;vertical-align:-0.0833em;"></span><span class="mord">2</span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span><span class="mord mathnormal">n</span></span></span></span> é um inteiro, obtivemos o quadrado de nosso número ímpar na forma <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><mi>m</mi><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">2m+1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7278em;vertical-align:-0.0833em;"></span><span class="mord">2</span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span> para algum inteiro <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">m</span></span></span></span>, e então mostramos que seu quadrado é ímpar.</p>
<h1>Prova</h1>
<p>Estamos agora prontos para provar que a raiz quadrada de 2 não é um número racional. Suponhamos que seja. Isso significa que podemos achar um número racional <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi></mrow><annotation encoding="application/x-tex">a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">a</span></span></span></span>, tal que <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>a</mi><mn>2</mn></msup><mo>=</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">a²=2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span></span></span></span>. Podemos escrever</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>a</mi><mo>=</mo><mfrac><mi>m</mi><mi>n</mi></mfrac></mrow><annotation encoding="application/x-tex">a=\frac{m}{n}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.7936em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.1076em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">n</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
<p>onde <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mo separator="true">,</mo><mi>n</mi></mrow><annotation encoding="application/x-tex">m,n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">m</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">n</span></span></span></span> são inteiros, e nem <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">m</span></span></span></span> nem <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> é <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0</mn></mrow><annotation encoding="application/x-tex">0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0</span></span></span></span>. Além disso, podemos supor <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">m</span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> não simultaneamente pares porque, dividindo-os por <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn></mrow><annotation encoding="application/x-tex">2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span></span></span></span> quanto possível, podemos cancelar as potências de <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn></mrow><annotation encoding="application/x-tex">2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span></span></span></span> de pelo menos um deles. Assim, podemos admitir que <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">m</span></span></span></span> ou <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> é ímpar.</p>
<p>Da hipótese de que <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>a</mi><mn>2</mn></msup><mo>=</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">a²=2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span></span></span></span> obtemos <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>m</mi><mi mathvariant="normal">/</mi><mi>n</mi><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>=</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">(m/n)^2=2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0641em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">m</span><span class="mord">/</span><span class="mord mathnormal">n</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span></span></span></span>, ou</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mfrac><msup><mi>m</mi><mn>2</mn></msup><msup><mi>n</mi><mn>2</mn></msup></mfrac><mo>=</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">\frac{m^2}{n²}=2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.1771em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.4911em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7401em;"><span style="top:-2.989em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span></span></span></span></span>
<p>Multiplicando ambos os membros desta equação por <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>n</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">n²</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span> obtemos</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mi>m</mi><mn>2</mn></msup><mo>=</mo><mn>2</mn><msup><mi>n</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">m²=2n²</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8641em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8641em;"></span><span class="mord">2</span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span></span>
<p>e <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>m</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">m²</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span> é então par. Pelo que vimos acima, isto significa que <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">m</span></span></span></span> é par e podemos escrever <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mo>=</mo><mn>2</mn><mi>k</mi></mrow><annotation encoding="application/x-tex">m=2k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span> para algum inteiro <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>. Substituindo, obtemos</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">(</mo><mn>2</mn><mi>k</mi><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>=</mo><mn>2</mn><msup><mi>n</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">(2k)²=2n²</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.1141em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8641em;"></span><span class="mord">2</span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span></span>
<p>ou <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>4</mn><msup><mi>k</mi><mn>2</mn></msup><mo>=</mo><mn>2</mn><msup><mi>n</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">4k²=2n^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">4</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">2</span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span>. Cancelamos o <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn></mrow><annotation encoding="application/x-tex">2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span></span></span></span> e obtemos <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><msup><mi>k</mi><mn>2</mn></msup><mo>=</mo><msup><mi>n</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">2k²=n²</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">2</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span>. Isto significa que <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>n</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">n²</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span> é par e, consequentemente, pelo que vimos acima, que <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> é par. Concluímos assim que <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">m</span></span></span></span> e <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span> são pares, o que contradiz o fato de que pelo menos um deles é ímpar. Podemos então concluir que não existe nenhuma fração <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mi mathvariant="normal">/</mi><mi>n</mi></mrow><annotation encoding="application/x-tex">m/n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">m</span><span class="mord">/</span><span class="mord mathnormal">n</span></span></span></span> cujo quadrado seja <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn></mrow><annotation encoding="application/x-tex">2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span></span></span></span>.</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msqrt><mn>2</mn></msqrt><mo>⊂</mo><mi mathvariant="double-struck">I</mi></mrow><annotation encoding="application/x-tex">\sqrt{2} \subset \mathbb{I}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.0839em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9561em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.9161em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width="400em" height="1.08em" viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.0839em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">⊂</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6889em;"></span><span class="mord mathbb">I</span></span></span></span></span>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>math</category>
            <category>proof</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/raiz-de-2-e-inrracional/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[My first search function]]></title>
            <link>https://mateusf.com/blog/post/my-first-search-function</link>
            <guid>my-first-search-function</guid>
            <pubDate>Thu, 13 Jul 2023 14:27:04 GMT</pubDate>
            <description><![CDATA[Archive of how I implemented a search algorithm with Typescript]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/my-first-search-function/thumbnail" alt=""> # The Search Algorithm</p>
<p>I had a component in my website for search through my blog posts, the component consisted in a modal with a search input on top, and the list of posts after the input, here is an screenshot:</p>
<p><img src="assets/screenshot.png" alt="screenshot.png"></p>
<p>The modal is triggered by an button that looks like another input search (<em>but isn't</em>) with a keyboard shortcut (<code>Ctrl+K</code>).</p>
<p>All of this was made using Tailwindcss, Phosphor icons, Radix UI and Geist UI (<em>for the keyboard shortcut</em>) on Next.js.</p>
<p>The initial post list is a random list, then, when a search input is detected, a function is called, for get the input and return the matched post. This function is the main topic of this post.</p>
<p>I'm dropping this implementation now, for use a more better, modern and complete alternative: The <a href="https://github.com/timc1/kbar">kbar</a> library.</p>
<p>I will not talk about kbar now, but I prefer to use him instead of my own, pure, implementation of search modal, but I sincerely like my search function, is simple, and precise. I think that there is better search algorithm that will fit better in my use case, but is my first search function, and I want to register/archive my implementation. If you know another search algorith, feel free to share in the comments section bellow, any link, reference, topic... Anything!</p>
<p>Well, here is:</p>
<pre><code class="language-typescript">import { Post } from 'contentlayer/generated'
import { slug } from '@/shared/lib/slug'

export function searchMath(post: Post, search: string) {
  const sluggedSearch = slug(search)

  let weight = 0
  const sources = [
    post.title,
    post.description,
    post.author,
    post.category,
    post.status,
    post.tags
  ]

  sources.forEach(source => slug(source).includes(sluggedSearch) &#x26;&#x26; weight++)

  return weight
}
</code></pre>
<p>Well, let me explain...</p>
<p>The <code>Post</code> here is an interface for my defined Post on contentlayer, it's not relevant to write a detailed explanation about it, but you can check the types of the properties bellow:</p>
<table>
<thead>
<tr>
<th>prop</th>
<th>type</th>
<th>example</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>title</code></td>
<td>String</td>
<td>"Why Galo is the biggest of Minas"</td>
</tr>
<tr>
<td><code>description</code></td>
<td>String</td>
<td>"Mariaa, eu sei que você tremee... 🎶"</td>
</tr>
<tr>
<td><code>author</code></td>
<td>String</td>
<td>"Mateus Felipe Gonçalves"</td>
</tr>
<tr>
<td><code>category</code></td>
<td>String</td>
<td>"Article"</td>
</tr>
<tr>
<td><code>status</code></td>
<td>Enum</td>
<td>"Published"</td>
</tr>
<tr>
<td><code>tags</code></td>
<td>String</td>
<td>"galo, maria, futebol, campeonato mineiro"</td>
</tr>
</tbody>
</table>
<p>The <code>slug</code> function is just to get a string and return a slugged version of it (e.g. "Clube Atlético Mineiro" to "clube-atletico-mineiro").</p>
<p>The logic is to attach a weight to the post, that represents how close the post is to the target search, using a weight number between 0-n (<em><strong>n</strong> is the number of sources to consider, in this case is 6</em>). With a list of Posts and their respective weights, we can purge all the posts with weight 0 (<em>posts that not match the search</em>) and sort the rest based on weight value, from biggest value (<em>most matching post</em>) to lowest value (<em>least matching post</em>).</p>
<p>Implementation: <a href="https://github.com/mateusfg7/mateusf.com/blob/7.3.0/src/shared/lib/match.ts">https://github.com/mateusfg7/mateusf.com/blob/7.3.0/src/shared/lib/match.ts</a></p>
<h2>My mistake</h2>
<p>While I was reading my code, I notice that the search isn't case-sensitive, because I transform all to a slug version, and compare this slugged version of the strings.</p>
<p>This ends up decreasing the accuracy of the search, and this "String Processor" it's useless, in fact, it just gets in the way.</p>
<p>I process all the string with the <code>slug</code> function because I already had problems with compare string without process on post titles to get the reference of posts, but this it's not the case.</p>
<p><strong>Moral of the story</strong>:  beware of "muscle memory" of your brain!</p>
<h1>Observation</h1>
<p>I was not honest when I said this is my first search implementation, I made another before, but it not have the concept of <em>weight</em>, is just a match script. This script it's self explanatory, so I won't go into details about how it works:</p>
<pre><code class="language-typescript">import { Post } from 'contentlayer/generated'
import { slug } from './utils'

export function searchMath(post: Post, search: string) {
  const sluggedSearch = slug(search)

  if (slug(post.title).includes(sluggedSearch)) return true
  if (slug(post.description).includes(sluggedSearch)) return true
  if (slug(post.author).includes(sluggedSearch)) return true
  if (slug(post.category).includes(sluggedSearch)) return true
  if (slug(post.status).includes(sluggedSearch)) return true
  if (slug(post.tags).includes(sluggedSearch)) return true

  return false
}
</code></pre>
<p>Implementation: <a href="https://github.com/mateusfg7/mateusf.com/blob/6.0.0/src/lib/match.ts">https://github.com/mateusfg7/mateusf.com/blob/6.0.0/src/lib/match.ts</a></p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>javascript</category>
            <category>typescript</category>
            <category>search</category>
            <category>algorithm</category>
            <category>react</category>
            <category>next.js</category>
            <category>radix-ui</category>
            <category>geist-ui</category>
            <category>tailwindcss</category>
            <category>archive</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/my-first-search-function/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Intuição e aleatoriedade]]></title>
            <link>https://mateusf.com/blog/post/intuicao-e-aleatoriedade</link>
            <guid>intuicao-e-aleatoriedade</guid>
            <pubDate>Mon, 03 Jul 2023 20:44:29 GMT</pubDate>
            <description><![CDATA[Trecho do livro "O Andar do Bêbado" em que o autor conta sobre a passagem de Daniel Kahneman como instrutor de um grupo de instrutores de voo e suas observações acerca do fenômeno estatístico "Regressão à Média"]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/intuicao-e-aleatoriedade/thumbnail" alt=""> # Transcrição</p>
<p>Em 2002, O <a href="https://www.nobelprize.org/">Prêmio Nobel</a> de economia foi concedido a um cientista chamado <a href="https://pt.wikipedia.org/wiki/Daniel_Kahneman">Daniel Kahneman</a>. Hoje em dia, os economistas fazem todo tipo de coisa - explicam porque os professores recebem salários tão baixos, porquê os times de futebol valem tanto dinheiro e porque as funções corporais ajudam a estabelecer um limite para o tamanho das criações de porcos (um porco produz de três a cinco vezes mais excrementos que uma pessoa, portanto uma fazendinha com milhares de porcos costuma produzir mais detritos que as cidades vizinhas). Apesar das grandes pesquisas feitas por economistas, o Nobel de 2002 foi excepcional, porque Kahneman não é economista. É psicólogo, e durante décadas, ao lado do falecido <a href="https://pt.wikipedia.org/wiki/Amos_Tversky">Amos Tversky</a>, estudou e esclareceu os tipos de percepções equivocadas sobre a aleatoriedade que alimentam muitas das falácias comuns de que falarei neste livro.</p>
<p>O maior desafio à compreensão do papel da aleatoriedade na vida é o fato de que, embora os princípios básicos dela surjam da lógica cotidiana, muitas das consequências que se seguem a esses princípios provam-se contra intuitivas. Os próprios estudos de Kahneman e Tversky foram desencadeados por um evento aleatório. Em meados dos anos 1960, Kahneman, que começava então sua carreira como professor de Universidade Hebraica, concordou em realizar um trabalho pouco emocionante: dar aulas a um grupo de instrutores de voo da Aeronáutica israelense sobre os pressupostos convencionais das mudanças de comportamento e suas aplicações à psicologia do treinamento de voo. Ele deixou claro de que a estratégia de recompensar comportamentos positivos funciona bem, ao contrário da de punir equívocos. Um de seus alunos o interrompeu, expressando uma opinião que acabaria por levar o cientista a uma epifania e por guiar suas pesquisas pelas décadas seguintes.</p>
<p>"Muitas vezes elogiei entusiasticamente meus alunos por manobras muito bem executadas, e na vez seguinte sempre se saíram pior", disse o instrutor de voo. "E já gritei com eles por manobras mal executadas, e geralmente melhoram na vez seguinte. Não venha me dizer que a recompensa funciona e a punição não. Minha experiência contradiz essa ideia." Os outros instrutores concordaram. Para Kahneman, a experiência deles parecia genuína. Por outro lado, ele acreditava nos experimentos com animais que demonstravam que a recompensa funcionava melhor que a punição. Ele meditou sobre esse aparente paradoxo. E então se deu conta: os gritos precediam a melhora, porém, ao contrário do que parecia, não a causavam.</p>
<p>Como era possível? A resposta se encontra num fenômeno chamado <a href="https://pt.wikipedia.org/wiki/Regress%C3%A3o_%C3%A0_m%C3%A9dia">regressão à média</a>. Isto é, em qualquer série de eventos aleatórios, há uma grande probabilidade de que um acontecimento extraordinário seja seguido, em virtude puramente do acaso, por um acontecimento mais corriqueiro. Funciona assim: cada aprendiz possui uma certa habilidade pessoal para pilotar jatos de caça. A melhora em seu nível de habilidade envolve diversos fatores e requer ampla prática; portanto, embora sue habilidade esteja melhorando lentamento ao longo do treinamento, a variação não será perceptível de uma manobra para a seguinte.  Qualquer desempenho especialmente bom ou ruim será, em sua maior parte, uma questão de sorte. Assim, se um piloto fizer um pouso excepcionalmente bom, bem acima do seu nível normal de performance, haverá uma boa chance de que, no dia seguinte, essa performance se aproxime mais da <strong>norma</strong> - ou seja, <strong>piore</strong>. E se o instrutor tiver elogiado, ficará com a impressão de que o elogio não teve efeito positivo. Porém, se um piloto fizer um pouco excepcionalmente ruim - derrapar com o avião no fim da pista, entrando no tonel de sopa da lanchonete da base -, haverá uma boa chance de que, no dia seguinte, sua performance se aproxime mais da <strong>norma</strong> - ou seja, <strong>melhore</strong>.  E se seu instrutor estiver o hábito de gritar "Seu jegue estabanado!", sempre que algum aluno tiver um desempenho ruim, ficará com a impressão de que a crítica teve efeito positivo. Dessa maneira surgiria um <em>aparente</em> padrão: aluno faz boa manobra, elogio tem efeito negativo; aluno faz manobra ruim, instrutor compara aluno a asinino em altos brados, aluno melhora. A partir de tais experiências, os instrutores concluíram que seus gritos constituíam uma eficaz ferramenta educacional. Na verdade, não faziam nenhuma diferença.</p>
<h1>Referência</h1>
<p>Mlodinow, Leonard. <strong>O Andar do Bêbado</strong> ISBN-13 <em>9788537801550</em>. 2009. p.15-16</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>intuição</category>
            <category>aleatoriedade</category>
            <category>estatística</category>
            <category>probabilidade</category>
            <category>filosofia</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/intuicao-e-aleatoriedade/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Entropia no software e a teoria da Janela Quebrada]]></title>
            <link>https://mateusf.com/blog/post/entropia-no-software-e-a-teoria-da-janela-quebrada</link>
            <guid>entropia-no-software-e-a-teoria-da-janela-quebrada</guid>
            <pubDate>Mon, 19 Jun 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Salvando o artigo "Entropia no software e a teoria da janela quebrada: Como afeta seu dia a dia?" de Rafael dos Santos Miguel Filho.]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/entropia-no-software-e-a-teoria-da-janela-quebrada/thumbnail" alt=""> # Introdução</p>
<p>Sim, você ouviu direito: <em>Entropia no Software e a Teoria da Janela Quebrada</em>. Pode parecer um pouco estranho no começo, talvez até esteja se perguntando "mas o que esses conceitos têm a ver com o mundo do software?". Esses dois conceitos não são termos comumente associados um ao outro, mas ao explorar mais a fundo, descobrimos que essas duas teorias podem oferecer uma perspectiva única sobre a gestão eficaz do desenvolvimento e manutenção de software. Neste artigo, exploramos como esses dois conceitos se inter-relacionam e como podem ser utilizados para melhorar as práticas de desenvolvimento de software.</p>
<h1>Entropia</h1>
<p>Parece um termo científico complicado, não é? Não se preocupe, juntos vamos desmistificar essa palavra e entender o que ela realmente significa, especialmente quando aplicada ao mundo do software. Pegue um café e vamos lá! ☕</p>
<p>Vamos começar no século XIX (19), com um cientista chamado <a href="https://pt.wikipedia.org/wiki/Rudolf_Clausius"><em>Rudolf Clausius</em></a>. Foi ele quem nos apresentou a entropia no mundo da termodinâmica. Mas como isso pode ser comparado ao desenvolvimento de software? Prometo que vamos chegar lá, mas antes vamos entender um pouco mais sobre o que Clausius queria dizer com entropia.</p>
<p>Entropia, no campo da física, <strong>é uma forma de medir a imprevisibilidade ou, como alguns preferem simplificar, a "desordem" dentro de um sistema</strong>. Agora, quando falo em "desordem", não quero dizer bagunça no sentido comum da palavra. Na verdade, estou falando sobre como a energia está distribuída em um sistema.</p>
<p>Imagine que temos uma caixa cheia de partículas. Se todas essas partículas estiverem concentradas em um único canto, podemos dizer que a entropia é baixa - há uma certa "ordem". Mas, se as partículas estão espalhadas de maneira aleatória por toda a caixa, aí temos uma alta entropia - a distribuição de energia é mais "imprevisível" ou "desordenada". A natureza tende ao estado de maior entropia, ou seja, as partículas irão se dispersar, <strong><em>a menos que algo externo intervenha</em></strong>. É como se a natureza gostasse de um pouco de imprevisibilidade</p>
<p>Agora, chegou a hora de conectar essa ideia com o mundo do software 🌉. <strong>Quando falamos em entropia no desenvolvimento de software, estamos nos referindo a essa tendência natural dos sistemas de software de se tornarem mais complexos e "desordenados" com o passar do tempo</strong>. E quando falo "desordem" aqui, estou falando de coisas como código mal estruturado, documentação insuficiente, bugs não corrigidos, <em>code smells</em>, e por aí vai.</p>
<p>O que acontece é que conforme o software cresce e evolui, é preciso esforço constante para evitar que essa entropia aumente. Precisamos trabalhar para manter o sistema organizado e eficiente - similar a como as partículas na caixa necessitam de uma força externa para não se espalharem aleatoriamente.</p>
<p>Agora que entendemos rapidamente o que é entropia, vamos entender alguns pontos que podem contribuir para o seu aumento dentro do software. Vou aproveitar essa parte para comentar algumas que, infelizmente, já presenciei também na indústria de software.</p>
<h1>A falta de requisitos claros!</h1>
<p>Vou compartilhar com você uma história que, apesar de fictícia, poderia facilmente se passar na realidade de muitas equipes de desenvolvimento de software. Prometo que é uma história com uma lição valiosa para todos nós: programadores, gerentes de projeto, product owners e qualquer um interessado em construir produtos de software de sucesso.</p>
<p>Pense em uma startup inovadora que está desenvolvendo um aplicativo de entrega de alimentos. Entre os muitos recursos desse aplicativo, surge um requisito especial: a opção de os usuários compartilharem um pedido com amigos, permitindo que todos adicionem seus itens preferidos à mesma ordem. Isso parece um diferencial competitivo incrível, não é mesmo?</p>
<p>No entanto, a descrição desse requisito é um pouco vaga e não entra em detalhes sobre como essa funcionalidade deve ser implementada. Deve existir um limite de usuários por pedido compartilhado? Como lidar com a divisão dos custos de entrega?</p>
<p>Nosso time de desenvolvimento, sempre buscando a eficiência, interpreta o requisito da melhor forma possível com as informações disponíveis. Eles decidem que não haverá limites para a quantidade de usuários em um pedido compartilhado, e que os custos de entrega serão divididos igualmente entre todos os participantes.</p>
<p>Quando o recurso é lançado, a reação dos usuários é mista. Alguns adoram a ideia, mas outros ficam frustrados. Eles não acham justo que um usuário que adicionou apenas um item pequeno pague a mesma taxa de entrega de alguém que pediu vários itens maiores. A falta de limites também causa problemas, com pedidos gigantescos causando atrasos nas entregas.</p>
<p>A lição aqui? Requisitos mal definidos podem levar a mal-entendidos, <strong>implementações imprecisas</strong> e até mesmo a um feedback negativo dos usuários.</p>
<p>Portanto, <strong>cada vez que um novo recurso é proposto, é fundamental não aceitarmos requisitos que pareçam insuficientemente detalhados ou que não estejam coerentes com a realidade</strong>. Esse é um dever compartilhado: a equipe de especialistas do domínio deve se esforçar para esclarecer as funcionalidades, enquanto os gestores de tecnologia precisam estar prontos para questionar e clarificar qualquer requisito que pareça vago.</p>
<p><em><strong>E como isso afeta e colabora para a alta desordem do software?</strong></em></p>
<p>Quando um recurso é implementado com base em requisitos mal definidos, pode levar a um código mal estruturado ou a uma <em><strong>arquitetura de software que não está alinhada com a verdadeira necessidade do negócio</strong></em>. Isso pode causar problemas, como dificuldades de manutenção, problemas de performance e até a introdução de bugs. Além disso, se os desenvolvedores precisam revisitar continuamente o recurso para corrigir mal-entendidos ou implementar mudanças, isso pode causar ainda mais complexidade e "desordem".</p>
<p>Isso gera estresse para a equipe. Afinal, provavelmente recursos que não foram planejados corretamente precisam de novas definições e modelagem de dados. Talvez novas tabelas precisem ser criadas, novos relacionamentos e entidades. Isso consequentemente pode gerar prazos de entregas irrealistas para correr atrás do prejuízo. Sabemos que muitas empresas deixam de lado em momentos críticos a qualidade, muitos recursos novos ou até os já existentes podem precisar de uma revisão completa, <strong>mas isso não é feito com qualidade</strong>. Percebe a cascata de problemas gerados? <strong>Isso é a desordem</strong>!</p>
<p>Portanto, requisitos mal definidos aumentam a entropia tanto no software quanto no negócio. Eles contribuem para um código mais caótico e complexo e podem levar a resultados de negócios indesejados. Ao mesmo tempo, lidar com esses requisitos e suas consequências demanda tempo e recursos, que poderiam ser usados para criar novos recursos ou melhorar outros aspectos do sistema. É por isso que é tão importante se esforçar para definir claramente os requisitos desde o início.</p>
<h1>Má Comunicação entre equipes!</h1>
<p>Vamos explorar um outro cenário bastante comum no mundo do desenvolvimento de software. Este é especialmente relevante se você já fez parte de uma equipe de desenvolvimento.</p>
<p>Vamos visualizar uma startup, trabalhando em um aplicativo de rede social. Temos dois times, temos um desenvolvedor encarregado de construir uma <a href="https://aws.amazon.com/pt/what-is/api/">API</a> que é o coração do sistema de notificação do aplicativo, responsável por alertar os usuários sobre novos likes, comentários e mensagens.</p>
<p>Por outro lado, temos outro programador, em outra equipe, cuja tarefa é desenvolver a interface de usuário (frontend) que exibirá essas notificações. Este desenvolvedor depende da API para receber esses dados e exibi-los de forma intuitiva e atraente para os usuários.</p>
<p>Agora, imagine que o desenvolvedor responsável pela API, na busca pela excelência, faz algumas melhorias significativas, otimizando a forma como os dados são entregues. No entanto, esquece-se de informar ao colega que depende dessa API sobre as mudanças realizadas, ou sobre a nova versão do serviço.</p>
<p>O programador frontend, completamente alheio à atualização, continua a trabalhar com a versão antiga da API. Quando o aplicativo é lançado, os usuários começam a reclamar que as notificações não estão funcionando como esperado, ou até mesmo aparecendo de forma errada.</p>
<p>A situação acima ilustra como um simples deslize na comunicação pode conduzir a um aumento na entropia do software. Essa disfunção não apenas introduz bugs, mas também pode causar frustração e confusão na equipe, e pior ainda, insatisfação no usuário final.</p>
<p>Portanto, a lição aqui é clara: <strong>a comunicação eficaz é fundamental para controlar a entropia no software</strong>. Manter todos na equipe informados sobre as mudanças e atualizações pode evitar equívocos e garantir que todos estejam alinhados, contribuindo para um software mais eficiente e um ambiente de trabalho mais harmônico.</p>
<p><em><strong>E como a situação acima colabora para a alta desordem do software?</strong></em></p>
<p>A situação descrita acima contribui significativamente para a alta entropia do software, ou desordem, de várias maneiras. Vamos dividi-la em pedaços para entender melhor.</p>
<ol>
<li><strong>Código Desatualizado ou Incompatível:</strong> O desenvolvedor que trabalha na interface do usuário está usando uma versão desatualizada da API. Isto pode levar a inconsistências no código, erros de compatibilidade e até mesmo falhas no sistema. Além disso, pode haver um impacto na performance do sistema.</li>
<li><strong>Esforço Desnecessário:</strong> A equipe agora terá que gastar tempo extra corrigindo os problemas causados pela falta de comunicação. Isso significa tempo de desenvolvimento perdido que poderia ter sido usado para adicionar novos recursos ou melhorar outros aspectos do software.</li>
<li><strong>Introdução de Bugs:</strong> A interface do usuário que depende da API desatualizada pode não funcionar como esperado, levando a bugs. Dependendo da gravidade desses bugs, eles podem afetar a experiência do usuário e até mesmo levar a perdas de dados.</li>
<li><strong>Insatisfação do Usuário:</strong> A experiência do usuário pode ser prejudicada devido a funcionalidades mal implementadas ou bugs. Isso pode levar a feedback negativo, perda de usuários e danos à reputação do produto.</li>
</ol>
<p>Esses fatores combinados aumentam a "desordem" ou entropia dentro do projeto de software. Eles criam uma situação onde a complexidade e a confusão dominam, dificultando a implementação de melhorias e correções. É por isso que a boa comunicação é tão crucial!</p>
<h1>Mudanças frequentes nos requisitos!</h1>
<p>Imagino que você já tenha se deparado com uma situação onde os requisitos para um software mudam constantemente, certo? Isso pode ser um grande desafio. Tais mudanças podem incluir novas funcionalidades, requisitos e processos que não foram considerados inicialmente. E o que isso causa? Aumento na complexidade do software, introdução de bugs e dificuldade para manter e evoluir o sistema.</p>
<p>Para ilustrar, vamos imaginar um programador desenvolvendo um software de gerenciamento de estoque. Durante o desenvolvimento, os requisitos estão em constante mudança: novos tipos de produtos são introduzidos, regras de desconto são alteradas e as informações dos produtos são variadas. Essa constante adaptação às mudanças pode resultar em uma arquitetura de software incerta e em constante fluxo.</p>
<p>Essa falta de estabilidade e clareza aumenta a entropia dentro do software. A fase de planejamento parece nunca chegar a uma conclusão definitiva, enquanto a lista de requisitos cresce e se transforma. A adição de caminhos de código desnecessários ou redundantes, em resposta a essas mudanças frequentes, pode levar a uma complexidade ainda maior, dificultando a compreensão do código e sua manutenção.</p>
<p>Além disso, com cada nova mudança, há um risco maior de introduzir bugs e falhas no software. Afinal, cada alteração requer uma revisão cuidadosa e testes completos para garantir que não está introduzindo novos problemas. Infelizmente, com prazos apertados e requisitos mal definidos, essa etapa crucial pode ser negligenciada, o que só aumenta a entropia do sistema.</p>
<p>Por fim, o que isso tudo tem a ver com o código que escrevemos? Bem, tudo! Quanto mais complexo o sistema se torna, mais difícil é para nós, desenvolvedores, entender e manter o código. Vamos conversar mais sobre esse assunto.</p>
<h1>O código indesejado</h1>
<p>A falta de diálogo entre as equipes, a falta de especificações claras e as mudanças frequentes nos requisitos podem impactar negativamente a forma como escrevemos código de várias maneiras:</p>
<p>Vamos começar com o <strong>Código inconsistente</strong>. Imagine uma equipe de desenvolvedores trabalhando em um projeto, mas com uma comunicação precária entre si. Isso pode resultar em diferentes interpretações dos requisitos e, portanto, inconsistências no código.</p>
<p>Agora, pense no <strong>Código mal mantido</strong>. Especificações nebulosas e mudanças constantes podem levar a um emaranhado de código "sujo", semelhante a um prédio mal conservado, que se torna cada vez mais difícil de manter.</p>
<p>Em seguida, temos os chamados "<strong>cheiros de código</strong>". Pense que está andando por uma rua e sente um odor desagradável. É um sinal de que algo não está limpo. No nosso código, os famosos <a href="https://refactoring.guru/refactoring/smells"><em>code smells</em></a>, são aspectos que sugerem <strong>problemas potenciais de qualidade ou design</strong>, geralmente provocados por mudanças frequentes nos requisitos ou até mesmo falta de experiencia dos programadores, falta de adoção de boas práticas entre outros fatores ligados a legibilidade do código.</p>
<p><strong>Código redundante</strong> também é um problema. Sem especificações claras, podemos encontrar partes do código repetidas, aumentando a complexidade e o tempo de manutenção, principalmente pela falta de clareza e adoção do princípio <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a>.</p>
<p>E quanto ao <strong>aumento de bugs</strong>? Isso pode ocorrer quando há falhas de comunicação e as especificações não são compreendidas corretamente. Mas principalmente ocorrem pela <strong>ausência de testes automatizados</strong> para validar os comportamentos que são esperados pelo software.</p>
<p><em><strong>Como muitos lidam com esses problemas citados, quando se tornam insustentáveis?</strong></em></p>
<p>Os desenvolvedores podem considerar refatorações significativas ou, em casos extremos, reescrever o software do zero. <strong>Mas atenção, essas são medidas de curto prazo</strong>. Se a equipe não adotar um <strong>plano consistente para controlar a entropia futura</strong>, a deterioração do código retornará. Mas o que tudo isso tem a ver com a teoria da janela quebrada?</p>
<h1>A teoria da janela quebrada</h1>
<p>No livro <a href="https://www.amazon.com.br/Pragmatic-Programmer-journey-mastery-Anniversary/dp/0135957052"><em><strong>The Pragmatic Programmer</strong></em></a>, os autores argumentam que a entropia do software é contagiosa e, se não for controlada, torna-se uma epidemia. Além disso, fazem uma analogia com a teoria da janela quebrada. Vamos estudar isso mais afundo.</p>
<p>Proposta pelos criminologistas <a href="https://www.britannica.com/topic/broken-windows-theory"><em><strong>James Wilson e George Kelling</strong></em></a> e tendo um enorme impacto na política policial durante a década de 1990, a teoria das janelas quebradas é uma ideia que sugere que a desordem física em um ambiente urbano, como pichações e vidraças quebradas, pode levar a um aumento da criminalidade naquela área ou degradação por vândalos no local.</p>
<p>Bom, você deve estar se perguntando, "Mas o que isso tem a ver com a entropia em software?" A resposta é: muito mais do que você imagina!</p>
<p>Considere um código com inconsistências, redundâncias, bugs ou mesmo code smells. Cada um desses elementos pode ser visto como uma "janela quebrada" na engenharia de software. Deixá-los sem solução, ou pior, <strong>permitir que se acumulem</strong>, gera uma crescente desordem - ou seja, a entropia do software. Essa alta entropia faz com que o código se torne cada vez mais difícil de manter, entender e evoluir.</p>
<p>De maneira similar à <a href="https://www.britannica.com/topic/broken-windows-theory"><em>Teoria da Janela Quebrada</em></a>, um código mal cuidado e desorganizado pode incentivar práticas ruins de programação. Imagine que um novo membro da equipe se depara com um código repleto de inconsistências e bugs. Se não houver um esforço consciente para manter a qualidade do código, esse novo membro pode ser levado a pensar: "<em>Se o código já está nesse estado, por que eu deveria me esforçar para escrever um código de qualidade?</em>".</p>
<p><strong>A consequência é um ciclo vicioso, onde a qualidade do software se deteriora, a produtividade diminui, os bugs aumentam e a entropia se torna incontrolável</strong>. Assim como em uma casa de bairro onde as janelas quebradas não são consertadas, a desordem acaba por tomar conta.</p>
<p>Podemos acrescentar ainda mais, códigos confusos sem documentação e <strong>testes inadequados podem indicar aos desenvolvedores e gerentes de projeto que a qualidade não é uma prioridade, levando a comportamentos e decisões inadequadas para o contexto</strong>. Isso pode incluir a adição de novos recursos sem levar em conta a manutenção, omitir refatorações necessárias e não monitorar a qualidade do código. Esses comportamentos inadequados podem levar a um efeito dominó de problemas, onde a entropia do código aumenta gradualmente.</p>
<blockquote>
<p>A relação entre a Teoria da Janela Quebrada e a entropia é esta: ambos são formas de entender a importância da manutenção contínua e do cuidado com os detalhes. Tanto em uma cidade quanto em um sistema de software, a desordem se instala quando permitimos que pequenos problemas se acumulem. E a maneira de combater isso é através do cuidado constante, da manutenção regular e da atenção aos detalhes.</p>
</blockquote>
<h1>Como tratar esse problema grave?</h1>
<p>A <em>primeira</em> coisa a se ter em mente é que <strong>qualidade e manutenção não são aspectos a serem considerados apenas no final</strong> de um projeto - eles devem estar presentes desde o início. Pare de pensar que testes e refatorações são perdas de tempo!</p>
<p><em>Segundo</em>, <strong>mantenha a comunicação</strong>. Parece simples, mas é crucial. É necessário que <em><strong>todos</strong></em> os membros da equipe, sejam desenvolvedores, gerentes, proprietários de produtos ou outras partes interessadas, estejam alinhados em termos de requisitos, prazos e objetivos. Dessa forma, podemos reduzir mal-entendidos e evitar inconsistências que contribuem para a entropia.</p>
<p><em>Terceiro</em>, <strong>ter uma política de código limpo e seguir as melhores práticas de codificação</strong>. Aqui entram padrões de codificação consistentes, revisões de código, testes automatizados e uma atitude proativa em relação à refatoração. Não se trata apenas de escrever código que funciona, mas de escrever código que outros possam entender e manter.</p>
<p><em>Quarto</em>, devemos <strong>prestar atenção à arquitetura do nosso software</strong>. Uma arquitetura bem planejada e escalável reduz a probabilidade de termos que realizar mudanças drásticas no futuro, que podem introduzir novos bugs e aumentar a complexidade e a entropia. Uma arquitetura planejada de maneira precipitada leva a complexidade desnecessária e a um conflitos de ideias entre desenvolvedores dentro do projeto.</p>
<p>Por fim, <strong>a gestão eficaz das mudanças</strong>. Mudanças <em><strong>são inevitáveis</strong></em> em qualquer projeto, mas a maneira como lidamos com elas pode fazer uma grande diferença. Uma abordagem ágil, que encoraja o feedback contínuo e a adaptação, pode ajudar a gerir as mudanças de uma forma que reduza a entropia ao invés de aumentá-la.</p>
<p>Cada janela quebrada que consertamos é um passo na direção certa. Cada bug corrigido, cada inconsistência eliminada, cada "cheiro de código" resolvido contribui para o controle da entropia. E, ao manter a entropia sob controle, garantimos que nosso software seja sustentável, escalável, testável, compreendido e, acima de tudo, um fácil de modificar e trabalhar.</p>
<h1>Como os testes ajudam a manter a entropia sobre controle?</h1>
<p>Os testes <strong>continuam sendo uma ferramenta subestimada por muitos desenvolvedores na luta contra a alta entropia no software</strong>. Por que? Já tentou montar um quebra-cabeças sem a imagem de referência? Bem, se você já o fez, sabe o quão complicado é montar a imagem. Testes, meus caros leitores, são como essa imagem de referência na construção do nosso grande quebra-cabeças de software. Sem uma imagem clara do sistema, não podemos saber exatamente o que um software faz, ou seja, seu propósito. Seus principais recursos e objetivos. <strong>Testes refletem os comportamentos do software, são um espelho do software, que podemos executar e entender pelo que cada pedaço de código é responsável</strong>!</p>
<p>Os testes de software, unitários, de integração, funcional, de stress, entre outros, têm um papel crucial na prevenção e controle da entropia do software. Como exatamente?</p>
<ol>
<li><strong>Detectando problemas mais cedo</strong>: Testes bem escritos ajudam a identificar bugs, inconsistências e falhas mais cedo, quando eles são mais fáceis (e mais baratos) de serem corrigidos. Testes automatizados executados regularmente garantem que qualquer "janela quebrada" seja prontamente detectada, evitando a propagação da entropia.</li>
<li><strong>Prevenindo a regressão</strong>: À medida que o software evolui, é fácil quebrar funcionalidades existentes sem perceber. Com uma suíte de testes abrangente, você tem uma rede de segurança que ajuda a prevenir esses problemas, garantindo que o software continue funcionando como esperado após cada mudança.</li>
<li><strong>Documentação viva</strong>: Testes são uma espécie de documentação viva do sistema, que descreve como ele deve funcionar. Ao consultar os testes, <em><strong>novos membros da equipe ou mesmo desenvolvedores veteranos podem entender melhor o código</strong></em>, mantendo a base de código consistente e minimizando a entropia.</li>
<li><strong>Melhora a qualidade do código</strong>: Testes incentivam os desenvolvedores a escreverem códigos mais modulares e independentes (fáceis de testar), o que por si só já contribui para reduzir a entropia.</li>
<li><strong>Fornece confiança para refatorar</strong> : Melhorar seu design sem alterar seu comportamento é uma atividade necessária para manter a entropia controlada. Testes fornecem a segurança de que, se algo quebrar durante a refatoração, será prontamente detectado.</li>
</ol>
<p>No livro que estou escrevendo que pretendo <em><strong>anunciar o nome em breve</strong></em>, falo sobre esses pontos de uma perspectiva mais prática para a indústria de software. Realmente quando levamos muito a sério os testes, temos ganhos significativos de produtividade no dia a dia ao programar novos recursos e manter os que já existem. Obviamente não é uma tarefa simples, existem desafios e principalmente compromisso com a qualidade.</p>
<p>Em conclusão, a Teoria da Janela Quebrada nos ensina que a tolerância a pequenas falhas ou "janelas quebradas" no nosso código pode levar a uma cascata de problemas. Os desenvolvedores podem começar a achar que é aceitável produzir código de baixa qualidade, ou ignorar os testes, aumentando assim a entropia. Ao abraçar boas práticas e manter um olhar atento para "janelas quebradas", podemos manter a entropia sob controle e assegurar que nossos projetos de software permaneçam saudáveis e sustentáveis.</p>
<p>Novamente, é mais fácil escrever do que colocar em prática, por isso estou centralizando em um livro esse tema para abordar com mais liberdade e profundidade esse assunto tão complexo e interessante que faz parte do nosso cotidiano.</p>
<p>Fico por aqui. Espero que tenham gostado! Muito obrigada pela leitura até o final, espero que as dicas possam ajudar no dia a dia! Até o próximo artigo! 😄🖐️</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>programming</category>
            <category>management</category>
            <category>architecture</category>
            <category>filosofia</category>
            <category>Clean Code</category>
            <category>structure</category>
            <category>productivity</category>
            <category>project</category>
            <category>archive</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/entropia-no-software-e-a-teoria-da-janela-quebrada/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Swap em sistemas BTRFS]]></title>
            <link>https://mateusf.com/blog/post/swap-em-sistemas-btrfs</link>
            <guid>swap-em-sistemas-btrfs</guid>
            <pubDate>Tue, 13 Jun 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Como criar um swap file em arquivos btrfs]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/swap-em-sistemas-btrfs/thumbnail" alt=""> # Introdução</p>
<p>O Linux divide sua RAM física (memória de acesso aleatório) em pedaços de memória chamados páginas. <em>Swapping</em>, ou troca, é o processo pelo qual uma página de memória é copiada para o espaço pré-configurado no disco rígido, chamado espaço swap ou espaço de troca ou swap space, para liberar essa página de memória. Os tamanhos combinados da memória física e do espaço swap são a quantidade de memória virtual disponível.</p>
<p>Os usuários podem criar um espaço swap durante a instalação ou em qualquer momento posterior, conforme desejado. O espaço swap pode ser usado para duas finalidades, estender a memória virtual além da memória física instalada (RAM), também conhecido como "ativar swap", e também para suporte de suspensão para disco.</p>
<p>Veja <a href="https://wiki.archlinux.org/title/Swap_(Portugu%C3%AAs)">esse artigo</a> no Arch Wiki para informações mais detalhadas.</p>
<h1>How To</h1>
<p>O btrf só comessou a suportar a utilização de swap files apartir do kernel 5.0.0, e exige alguns comandos extras:</p>
<p>Primeiro vamos criar um diretório <em>"non-snapshotted"</em> na raiz do sistema, onde estará nossos swap files</p>
<pre><code class="language-console">sudo btrfs subvolume create /swap
</code></pre>
<p>Agora vamos criar o swap file em si, com o comando próprio do btrfs, já passando o tamanho que queremos alocar:</p>
<pre><code class="language-console">sudo btrfs filesystem mkswapfile --size 10g --uuid clear /swap/swapfile
</code></pre>
<p><em>note em que estou criando um arquivo de <strong>10 gigabytes</strong> em <code>10g</code>, mas você pode passar o tamanho que quiser. Se <code>--size</code> for omitido, será criado um arquivo de 2GiB por padrão.</em></p>
<p>Depois de criado, vamos ativar o swap file com o comando padrão <code>swapon</code>:</p>
<pre><code class="language-console">sudo swapon /swap/swapfile
</code></pre>
<p>Para vermos se o swap que criamos está ativado. basta rodar o comando:</p>
<pre><code class="language-console">sudo swapon --show
</code></pre>
<p><img src="assets/screenshot_1.png" alt="screenshot_1.png"></p>
<p>Com o swap file criado e ativado, basta adicionarmos a configuração no arquivo <code>fstab</code> para que o sistema use-o automaticamente quado reiniciar:</p>
<pre><code class="language-bash">/swap/swapfile none swap defaults 0 0
</code></pre>
<hr>
<h1>Referências</h1>
<p>How to Create a Linux Swap File: <a href="https://phoenixnap.com/kb/linux-swap-file">https://phoenixnap.com/kb/linux-swap-file</a> [<a href="https://web.archive.org/web/20230613132919/https://phoenixnap.com/kb/linux-swap-file"><em>archive</em></a>]</p>
<p>Create a Linux Swap File: <a href="https://linuxize.com/post/create-a-linux-swap-file/">https://linuxize.com/post/create-a-linux-swap-file/</a> [<a href="https://web.archive.org/web/20230613133106/https://linuxize.com/post/create-a-linux-swap-file/"><em>archive</em></a>]</p>
<p>Swap file vs swap partition ? when to use what ? any disadvantages or advantage …: <a href="https://kodekloud.com/community/t/swap-file-vs-swap-partition-when-to-use-what-any-disadvantages-or-advantage/146383">https://kodekloud.com/community/t/swap-file-vs-swap-partition-when-to-use-what-any-disadvantages-or-advantage/146383</a> [<a href="https://web.archive.org/web/20230613133939/https://kodekloud.com/community/t/swap-file-vs-swap-partition-when-to-use-what-any-disadvantages-or-advantage/146383"><em>archive</em></a>]</p>
<p>Btrfs - ArchWiki: <a href="https://wiki.archlinux.org/title/Btrfs#Swap_file">https://wiki.archlinux.org/title/Btrfs#Swap_file</a> [<a href="https://web.archive.org/web/20230613134129/https://wiki.archlinux.org/title/Btrfs"><em>archive</em></a>]</p>
<p>btrfs(5) - Arch manual pages: <a href="https://man.archlinux.org/man/btrfs.5#SWAPFILE_SUPPORT">https://man.archlinux.org/man/btrfs.5#SWAPFILE_SUPPORT</a> [<a href="https://web.archive.org/web/20230613134710/https://man.archlinux.org/man/btrfs.5"><em>archive</em></a>]</p>
<p>Swap (Português): <a href="https://wiki.archlinux.org/title/Swap_(Portugu%C3%AAs)">https://wiki.archlinux.org/title/Swap_(Portugu%C3%AAs)</a> [<a href="https://web.archive.org/web/20230616141949/https://wiki.archlinux.org/title/Swap_%28Portugu%C3%AAs%29"><em>archive</em></a>]</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>linux</category>
            <category>swap</category>
            <category>disk</category>
            <category>memory</category>
            <category>brtfs</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/swap-em-sistemas-btrfs/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Co-localizaçao]]></title>
            <link>https://mateusf.com/blog/post/co-localizacao</link>
            <guid>co-localizacao</guid>
            <pubDate>Mon, 05 Jun 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Princípio da co-localização na organização de bases de código, de Kent C. Dodds.]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/co-localizacao/thumbnail" alt=""> # Introdução</p>
<blockquote>
<p>Esta é uma tradução da postagem original <a href="https://kentcdodds.com/blog/colocation">Colocation</a> de <a href="https://kentcdodds.com/">Kent C. Dodds</a>.</p>
</blockquote>
<p>Todos nós queremos ter bases de código fáceis de manter, então começamos com a melhor das intenções para tornar nossa base de código (ou nosso canto da base de código) sustentável e fácil de entender. Com o tempo, à medida que uma base de código cresce, pode se tornar cada vez mais difícil gerenciar dependências (JS, CSS, imagens, etc.). À medida que os projetos crescem, uma quantidade crescente de sua base de código se torna "conhecimento tribal" (conhecimento do qual apenas você ou alguns outros têm acesso) e esse tipo de conhecimento contribui para a "dívida técnica" (seja esse termo preciso <a href="https://twitter.com/ryanflorence/status/747983065738153985">ou não</a>).</p>
<p>Eu gosto de manter minhas bases de código gerenciáveis não apenas para mim (aquele que o escreveu), mas também para meus colegas de equipe, futuros mantenedores e para mim mesmo em 6 meses. Acho que todos podemos concordar que esse é um grande ideal pelo qual devemos nos esforçar em nossas bases de código. Existem muitas ferramentas e técnicas diferentes à nossa disposição para realizar isso.</p>
<h1>Vamos falar sobre comentários de código</h1>
<p>Não quero discutir se deve comentar seu código (você deveria) e sobre o que seus comentários devem ser (você explica por que está fazendo algo inesperado nos comentários para que as pessoas que vêm depois possam entender as decisões que foram tomadas que resultaram em o código inesperado ou estranho). (Ok, talvez eu queira falar um pouco sobre isso). Em vez disso, quero me concentrar em onde esses comentários de código são colocados. Geralmente "co-localizamos" esses comentários com o código que eles estão explicando, colocando-os o mais próximo possível do código relevante.</p>
<p>Considere por um minuto, se fizéssemos isso de forma diferente. E se colocarmos esses comentários em um arquivo totalmente separado. Um enorme arquivo <code>DOCUMENTATION.md</code> ou talvez até mesmo um diretório <code>docs/</code> que mapeia de volta para o nosso diretório <code>src/</code>. Parece divertido para você? Sim, para mim também não. Haveria alguns problemas sérios que encontraríamos ao não co-localizar nossos comentários com o código que está explicando.</p>
<ul>
<li><strong>Manutenibilidade</strong>: eles ficariam fora de sincronia ou desatualizados mais rapidamente (do que já estão). Moveríamos ou excluiríamos um arquivo <code>src/</code> sem atualizar o arquivo <code>docs/</code> correspondente.</li>
<li><strong>Aplicabilidade</strong>: as pessoas que olham para o código em <code>src/</code> podem perder um comentário importante em <code>docs/</code> ou não comentar seu próprio código porque não percebem que existe um arquivo <code>docs/</code> para o arquivo <code>src/</code> que estão editando.</li>
<li><strong>Facilidade de uso</strong>: a troca de contexto de um local para outro também seria um desafio com esse tipo de configuração. Ter que lidar com vários locais para arquivos pode tornar difícil garantir que você tenha tudo o que precisa para manter um componente.</li>
</ul>
<p>Definitivamente, poderíamos criar uma convenção para esse tipo de estilo de comentário de código, mas por que iríamos querer? Não é mais simples manter os comentários co-localizados com o código que estão explicando?</p>
<h1>E daí?</h1>
<p>Agora, você provavelmente está pensando consigo mesmo: "Sim, claro, é por isso que ninguém faz essa coisa de <code>docs/</code> e todo mundo apenas co-localiza seus comentários com o código. Isso é óbvio. Qual é o seu ponto?" Meu ponto é que os benefícios da co-localização estão em toda parte.</p>
<h1>HTML/Visualização</h1>
<p>Tome HTML, por exemplo. Todos os benefícios de co-localizar nossos comentários também se traduzem em nossos modelos. Antes de estruturas modernas como o React, você teria sua lógica de visualização e seus modelos de visualização em diretórios totalmente separados. Isso é vítima dos mesmos problemas descritos acima. Hoje em dia é muito mais comum colocar essas coisas <strong>exatamente no mesmo arquivo</strong> com React e Vue, por exemplo. Com Angular, se não estiver no mesmo arquivo, o arquivo de modelo está pelo menos próximo ao arquivo JS ao qual está associado.</p>
<h1>CSS</h1>
<p>Outro conceito ao qual isso se aplica bem é o CSS. Não vou discutir com você sobre os méritos do CSS-in-JS (é fantástico), mas os benefícios são de outro mundo. <a href="https://medium.com/seek-blog/a-unified-styling-language-d0c208de2660">Saiba mais aqui</a>.</p>
<h1>Testes</h1>
<p>Esse conceito de co-localização de arquivos também se aplica muito bem a testes de unidade. Quão comum é encontrar um projeto com um diretório <code>src/</code> e um diretório <code>test/</code> preenchido com testes de unidade que tentam espelhar o diretório <code>src/</code>? Todas as armadilhas descritas acima também se aplicam aqui. Eu provavelmente não iria tão longe a ponto de colocar os testes de unidade exatamente no mesmo arquivo, mas também não descarto totalmente isso como uma ideia interessante (a implementação é deixada como um exercício para o leitor).</p>
<p>Para ajudar a permitir uma base de código mais sustentável, devemos co-localizar nossos arquivos de teste com o arquivo ou grupo de arquivos que estão testando. Isso garante que, quando novas pessoas (ou eu mesmo em 6 meses) chegarem ao código, elas possam ver imediatamente que o módulo foi testado e usar esses testes como referência para aprender sobre o módulo. Quando eles fazem alterações, ele os lembra de atualizar (adicionar/remover/modificar) os testes para contabilizar suas alterações.</p>
<h1>Estado</h1>
<p>O estado do aplicativo/componente apresenta os mesmos benefícios. Quanto mais desconectado/indireto for seu estado da IU que o está usando, mais difícil será mantê-lo. A localização do estado tem ainda mais benefícios do que a capacidade de manutenção, mas também melhora o desempenho do seu aplicativo. Uma alteração de estado em um canto da árvore de componentes do aplicativo renderizará muito menos componentes do que uma alteração de estado no topo da árvore. Localize seu estado.</p>
<h1>Arquivos utilitários "reutilizáveis"</h1>
<p>Isso também se aplica a arquivos e funções "utilitárias". Imagine que você está escrevendo um componente e vê um bom pedaço de código que pode ser extraído em sua própria função. Você extrai e pensa: "Ah... aposto que muita gente poderia usar isso." Então você o retira e coloca no diretório <code>utils/</code> do seu aplicativo e segue em frente com sua vida.</p>
<p>Posteriormente, seu componente é excluído, mas o utilitário que você escreveu está fora de vista, fora da mente e permanece (junto com seus testes) porque a pessoa que o excluiu presumiu que era mais usado. Ao longo dos anos, os engenheiros trabalharam duro para garantir que a função e seus testes continuem a funcionar corretamente, mesmo sem perceber que não são mais necessários. Esforço desperdiçado e carga cognitiva.</p>
<p>Se, em vez disso, você tivesse deixado essa função diretamente no arquivo que a utilizou, a história seria completamente diferente. Não estou dizendo para não se incomodar com o teste de unidade de funções utilitárias complexas (por favor, faça), mas mantê-las mais perto de onde são necessárias ajuda a evitar problemas.</p>
<h1>O princípio</h1>
<p><strong>O conceito de co-localizaçao pode ser resumido a este princípio fundamental:</strong></p>
<p>Você também pode dizer: "As coisas que mudam juntas devem ser localizadas o mais próximo possível." (<a href="https://twitter.com/dan_abramov">Dan Abramov</a> disse algo assim para mim uma vez).</p>
<h1>Código aberto facilita</h1>
<p>Além de evitar os problemas discutidos anteriormente, há outros benefícios em estruturar seus projetos dessa maneira. Pegar um componente e transformá-lo em um projeto de código aberto geralmente é tão simples quanto copiar/colar a pasta para outro projeto e publicá-lo no npm. Em seguida, basta instalá-lo em seu projeto e atualizar suas instruções de <code>require</code>/<code>import</code> e pronto.</p>
<h1>Exceções</h1>
<p>Claro que há um bom argumento para a documentação que abrange todo ou parte de um sistema e como as coisas se integram. E onde você colocaria a integração ou os testes de ponta a ponta que abrangem os componentes? <em>Você pode pensar que essas são exceções</em>, mas na verdade elas podem se encaixar perfeitamente no princípio mencionado acima</p>
<p>Se eu tiver uma parte do meu aplicativo associada à autenticação do usuário e quiser documentar esse fluxo, posso colocar um arquivo <code>README.md</code> na pasta que contém todos os módulos associados à autenticação do usuário. Se eu precisar escrever testes de integração para esse fluxo, posso colocar o arquivo desses testes na mesma pasta.</p>
<p>Para testes de ponta a ponta, geralmente faz mais sentido ir na raiz do projeto. Eles vão além do próprio projeto e em outras partes do sistema, então faz sentido para mim que estejam em um diretório separado. Eles realmente não mapeiam para os arquivos <code>src/</code>. Na verdade, os testes E2E realmente não se importam com a forma como o <code>src/</code> está organizado. A refatoração e a movimentação de arquivos no diretório <code>src/</code> não devem exigir a alteração dos testes E2E.</p>
<h1>Conclusão</h1>
<p>Nosso objetivo aqui é construir um software que seja o mais simples possível de manter. Os mesmos benefícios de <strong>manutenibilidade</strong>, <strong>aplicabilidade</strong> e <strong>facilidade</strong> de uso que obtemos com a colocalização de nossos comentários, também obtemos com a colocalização de outras coisas. Se você nunca experimentou, recomendo que experimente.</p>
<p>P.S. Se você está preocupado em violar a "separação de preocupações", recomendo que verifique <a href="https://youtu.be/x7cQ3mrcKaY">esta palestra</a> de <a href="https://twitter.com/floydophone">Pete Hunt</a> e reavalie o que isso significa 😀.</p>
<p>P.P.S. Também devo observar que isso se aplica muito bem a imagens e a qualquer outro recurso também. E quando você usa uma ferramenta como o <a href="https://webpack.js.org/">webpack</a>, co-localizar esses recursos também é muito fácil. Honestamente, esta é uma das principais propostas de valor do webpack IMO.</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>patterns</category>
            <category>architecture</category>
            <category>code</category>
            <category>Clean Code</category>
            <category>javascript</category>
            <category>react</category>
            <category>html</category>
            <category>tradução</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/co-localizacao/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[S3 Plan - Solid Snake Simulation]]></title>
            <link>https://mateusf.com/blog/post/s3-plan-solid-snake-simulation</link>
            <guid>s3-plan-solid-snake-simulation</guid>
            <pubDate>Wed, 16 Nov 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[The Selection for Societal Sanity]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/s3-plan-solid-snake-simulation/thumbnail" alt=""> # Metadata</p>
<p>Colonel/Rose A.I speech - Raiden | <em>Metal Gear Solid 2</em></p>
<h1>Transcript</h1>
<p><strong>Colonel</strong>:<br>
To begin with -- we're not what you'd call -- human.Over the past two hundred years -- A kind of consciousness formed layer by layer in the crucible of the White House.It's not unlike the way life started in the oceans four billion years ago.The White House was our primordial soup, a base of evolution -- We are formless.We are the very discipline and morality that Americans invoke so often.How can anyone hope to eliminate us?As long as this nation exists, so will we.</p>
<p><strong>Raiden</strong>:<br>
Cut the crap! If you're immortal, why would you take away individual freedoms and censor the Net?</p>
<p><strong>Rose</strong>:<br>
Jack, don't be silly.</p>
<p><strong>Colonel</strong>:<br>
Don't you know that our plans have your interests -- not ours -- in mind?</p>
<p><strong>Raiden</strong>:<br>
What?</p>
<p><strong>Rose</strong>:<br>
Jack, listen carefully like a good boy!</p>
<p><strong>Colonel</strong>:<br>
The mapping of the human genome was completed early this century.<br>
As a result, the evolutionary log of the human race lay open to us.</p>
<p><strong>Rose</strong>:<br>
We started with genetic engineering, and in the end, we succeeded in digitizing life itself.</p>
<p><strong>Colonel</strong>:<br>
But there are things not covered by genetic information.</p>
<p><strong>Raiden</strong>:<br>
What do you mean?</p>
<p><strong>Colonel</strong>:<br>
Human memories, ideas.<br>
Culture.<br>
History.</p>
<p><strong>Rose</strong>:<br>
Genes don't contain any record of human history.</p>
<p><strong>Colonel</strong>:<br>
Is it something that should not be passed on?<br>
Should that information be left at the mercy of nature?</p>
<p><strong>Rose</strong>:<br>
We've always kept records of our lives.<br>
Through words, pictures, symbols...<br>
from tablets to books...</p>
<p><strong>Colonel</strong>:<br>
But not all the information was inherited by later generations.<br>
A small percentage of the whole was selected and processed, then passed on.<br>
Not unlike genes, really.</p>
<p><strong>Rose</strong>:<br>
That's what history is, Jack.</p>
<p><strong>Colonel</strong>:<br>
But in the current, digitized world, trivial information is accumulating every second, preserved in all its triteness.<br>
Never fading, always accessible.</p>
<p><strong>Rose</strong>:<br>
Rumors about petty issues, misinterpretations, slander...</p>
<p><strong>Colonel</strong>:<br>
All this junk data preserved in an unfiltered state, growing at an alarming rate.</p>
<p><strong>Rose</strong>:<br>
It will only slow down social progress, reduce the rate of evolution.</p>
<p><strong>Colonel</strong>:<br>
Raiden, you seem to think that our plan is one of censorship.</p>
<p><strong>Raiden</strong>:<br>
Are you telling me it's not!?</p>
<p><strong>Rose</strong>:<br>
You're being silly! What we propose to do is not to control content, but to create context.</p>
<p><strong>Raiden</strong>:<br>
Create context?</p>
<p><strong>Colonel</strong>:<br>
The digital society furthers human flaws and selectively rewards the development of convenient half-truths.<br>
Just look at the strange juxtapositions of morality around you.</p>
<p><strong>Rose</strong>:<br>
Billions spent on new weapons in order to humanely murder other humans.</p>
<p><strong>Colonel</strong>:<br>
Rights of criminals are given more respect than the privacy of their victims.</p>
<p><strong>Rose</strong>:<br>
Although there are people suffering in poverty, huge donations are made to protect endangered species.<br>
Everyone grows up being told the same thing.</p>
<p><strong>Colonel</strong>:<br>
"Be nice to other people."</p>
<p><strong>Rose</strong>:<br>
"But beat out the competition!"</p>
<p><strong>Colonel</strong>:<br>
"You're special."<br>
"Believe in yourself and you will succeed."</p>
<p><strong>Rose</strong>:<br>
But it's obvious from the start that only a few can succeed...</p>
<p><strong>Colonel</strong>:<br>
You exercise your right to "freedom" and this is the result.<br>
All rhetoric to avoid conflict and protect each other from hurt.<br>
The untested truths spun by different interests continue to churn and accumulate in the sandbox of political correctness and value systems.</p>
<p><strong>Rose</strong>:<br>
Everyone withdraws into their own small gated community, afraid of a larger forum.<br>
They stay inside their little ponds, leaking whatever "truth" suits them into the growing cesspool of society at large.</p>
<p><strong>Colonel</strong>:<br>
The different cardinal truths neither clash nor mesh.<br>
No one is invalidated, but nobody is right.</p>
<p><strong>Rose</strong>:<br>
Not even natural selection can take place here.<br>
The world is being engulfed in "truth".</p>
<p><strong>Colonel</strong>:<br>
And this is the way the world ends.<br>
Not with a bang, but a whimper.</p>
<p><strong>Rose</strong>:<br>
We're trying to stop that from happening.</p>
<p><strong>Colonel</strong>:<br>
It's our responsibility as rulers.<br>
Just as in genetics, unnecessary information and memory must be filtered out to stimulate the evolution of the species.</p>
<p><strong>Raiden</strong>:<br>
And you think you're qualified to decide what's necessary and not?</p>
<p><strong>Colonel</strong>:<br>
Absolutely.<br>
Who else could wade through the sea of garbage you people produce, retrieve valuable truths and even interpret their meaning for later generations?</p>
<p><strong>Rose</strong>:<br>
That's what it means to create context.</p>
<p><strong>Raiden</strong>:<br>
I'll decide for myself what to believe and what to pass on!</p>
<p><strong>Colonel</strong>:<br>
But is that even your own idea?</p>
<p><strong>Rose</strong>:<br>
Or something Snake told you?</p>
<p><strong>Colonel</strong>:<br>
That's the proof of your incompetence, right there.<br>
You lack the qualifications to exercise free will.</p>
<p><strong>Raiden</strong>:<br>
That's not true! I have the right --</p>
<p><strong>Rose</strong>:<br>
Does something like a "self" exist inside of you?</p>
<p><strong>Colonel</strong>:<br>
That which you call "self" serves as nothing more than a mask to cover your own being.</p>
<p><strong>Rose</strong>:<br>
In this era of ready-made 'truths', "self" is just something used to preserve those positive emotions that you occasionally feel...</p>
<p><strong>Colonel</strong>:<br>
Another possibility is that "self" is a concept you conveniently borrowed under the logic that it would endow you with some sense of strength...</p>
<p><strong>Raiden</strong>:<br>
That's crap!</p>
<p><strong>Colonel</strong>:<br>
Is it?<br>
Would you prefer that someone else tell you?<br>
Alright then.<br>
Explain it to him.</p>
<p><strong>Rose</strong>:<br>
Jack, you're simply the best! And you got there all by yourself!</p>
<p><strong>Raiden</strong>:<br>
Grrr...</p>
<p><strong>Colonel</strong>:<br>
Oh, what happened?<br>
Do you feel lost?<br>
Why not try a bit of soul-searching?</p>
<p><strong>Rose</strong>:<br>
Don't think you'll find anything, though...</p>
<p><strong>Colonel</strong>:<br>
Ironic that although "self" is something that you yourself fashioned, every time something goes wrong, you turn around and place the blame on something else.</p>
<p><strong>Rose</strong>:<br>
"It's not my fault. It's not your fault."</p>
<p><strong>Colonel</strong>:<br>
In denial, you simply resort to looking for another, more convenient "truth" in order to make yourself feel better.</p>
<p><strong>Rose</strong>:<br>
Leaving behind in an instant the so-called "truth" you once embraced.</p>
<p><strong>Colonel</strong>:<br>
Should someone like that be able to decide what is "truth"?</p>
<p><strong>Rose</strong>:<br>
Should someone like you even have the right to decide?</p>
<p><strong>Colonel</strong>:<br>
You've done nothing but abuse your freedom.</p>
<p><strong>Rose</strong>:<br>
You don't deserve to be free!</p>
<p><strong>Colonel</strong>:<br>
We're not the ones smothering the world.<br>
You are.</p>
<p><strong>Rose</strong>:<br>
The individual is supposed to be weak.<br>
But far from powerless -- a single person has the potential to ruin the world.</p>
<p><strong>Colonel</strong>:<br>
And the age of digitized communication has given even more power to the individual.<br>
Too much power for an immature species.</p>
<p><strong>Rose</strong>:<br>
Building a legacy involves figuring out what is wanted, and what needs to be done for that goal.<br>
All this, you used to struggle with.<br>
Now, we think for you.</p>
<p><strong>Colonel</strong>:<br>
We are your guardians after all.</p>
<p><strong>Raiden</strong>:<br>
You want to control human thought?<br>
Human behavior?</p>
<p><strong>Colonel</strong>:<br>
Of course.<br>
Anything can be quantified nowadays.<br>
That's what this exercise was designed to prove.</p>
<p><strong>Rose</strong>:<br>
You fell in love with me just as you were meant to, after all.<br>
Isn't that right, Jack?</p>
<p><strong>Colonel</strong>:<br>
Ocelot was not told the whole truth, to say the least.</p>
<p><strong>Rose</strong>:<br>
We rule an entire nation -- of what interest would a single soldier, no matter how able, be to us?</p>
<p><strong>Colonel</strong>:<br>
The S3 Plan does not stand for Solid Snake Simulation.<br>
What it does stand for is Selection for Societal Sanity...</p>
<h1>Video</h1>
<hr>
<h1>Refs</h1>
<p>MGS2 Colonel A.I speech: <a href="https://www.reddit.com/r/copypasta/comments/9l5ri2/mgs2_colonel_ai_speech/"><em>https://www.reddit.com/r/copypasta/comments/9l5ri2/mgs2_colonel_ai_speech/</em></a> <a href="https://web.archive.org/web/20221116201321/https://www.reddit.com/r/copypasta/comments/9l5ri2/mgs2_colonel_ai_speech/">[Archive]</a></p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>society</category>
            <category>Metal Gear</category>
            <category>games</category>
            <category>transcript</category>
            <category>talk</category>
            <category>Hideo Kojima</category>
            <category>filosofia</category>
            <category>geek</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/s3-plan-solid-snake-simulation/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Prefixos do SI]]></title>
            <link>https://mateusf.com/blog/post/prefixos-do-si</link>
            <guid>prefixos-do-si</guid>
            <pubDate>Fri, 21 Jan 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Prefixos do Sistema Internacional de Unidades e suas representações]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/prefixos-do-si/thumbnail" alt=""> # <strong>Cheat Sheet</strong>: <em>Sistema Internacional de Unidades</em></p>
<table>
<thead>
<tr>
<th align="center">Prefixo</th>
<th align="center">Símbolo</th>
<th align="center"><strong>Notação Tradicional</strong></th>
<th align="center">Potências <em>(Base 10)</em></th>
<th align="center">Nome</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">Yotta</td>
<td align="center">Y</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1000000000000000000000000</mn></mrow><annotation encoding="application/x-tex">1 000 000 000 000 000 000 000 000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1000000000000000000000000</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mn>24</mn></msup></mrow><annotation encoding="application/x-tex">10^{24}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">24</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Septilhão</td>
</tr>
<tr>
<td align="center">Zetta</td>
<td align="center">Z</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1000000000000000000000</mn></mrow><annotation encoding="application/x-tex">1 000 000 000 000 000 000 000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1000000000000000000000</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mn>21</mn></msup></mrow><annotation encoding="application/x-tex">10^{21}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">21</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Sextilhão</td>
</tr>
<tr>
<td align="center">Exa</td>
<td align="center">E</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1000000000000000000</mn></mrow><annotation encoding="application/x-tex">1 000 000 000 000 000 000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1000000000000000000</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mn>18</mn></msup></mrow><annotation encoding="application/x-tex">10^{18}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">18</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Quintilhão</td>
</tr>
<tr>
<td align="center">Peta</td>
<td align="center">P</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1000000000000000</mn></mrow><annotation encoding="application/x-tex">1 000 000 000 000 000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1000000000000000</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mn>15</mn></msup></mrow><annotation encoding="application/x-tex">10^{15}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">15</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Quadrilhão</td>
</tr>
<tr>
<td align="center">Tera</td>
<td align="center">T</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1000000000000</mn></mrow><annotation encoding="application/x-tex">1 000 000 000 000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1000000000000</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mn>12</mn></msup></mrow><annotation encoding="application/x-tex">10^{12}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">12</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Trilhão</td>
</tr>
<tr>
<td align="center">Giga</td>
<td align="center">G</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1000000000</mn></mrow><annotation encoding="application/x-tex">1 000 000 000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1000000000</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mn>9</mn></msup></mrow><annotation encoding="application/x-tex">10^{9}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">9</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Bilhão</td>
</tr>
<tr>
<td align="center">Mega</td>
<td align="center">M</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1000000</mn></mrow><annotation encoding="application/x-tex">1 000 000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1000000</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mn>6</mn></msup></mrow><annotation encoding="application/x-tex">10^{6}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Milhão</td>
</tr>
<tr>
<td align="center">kilo</td>
<td align="center">k</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1000</mn></mrow><annotation encoding="application/x-tex">1 000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1000</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mn>3</mn></msup></mrow><annotation encoding="application/x-tex">10^{3}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Mil</td>
</tr>
<tr>
<td align="center">hecto</td>
<td align="center">h</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>100</mn></mrow><annotation encoding="application/x-tex">100</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">100</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">10^{2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Cem</td>
</tr>
<tr>
<td align="center">deca</td>
<td align="center">da</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>10</mn></mrow><annotation encoding="application/x-tex">10</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">10</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mn>1</mn></msup></mrow><annotation encoding="application/x-tex">10^{1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Dez</td>
</tr>
<tr>
<td align="center">Unidade Fundamental</td>
<td align="center">UF</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mn>0</mn></msup></mrow><annotation encoding="application/x-tex">10^{0}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mn>0</mn></msup></mrow><annotation encoding="application/x-tex">10^{0}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Um</td>
</tr>
<tr>
<td align="center">deci</td>
<td align="center">d</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mi mathvariant="normal">/</mi><mn>10</mn></mrow><annotation encoding="application/x-tex">1/10</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1/10</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mrow><mo>−</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">10^{-1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Décimo</td>
</tr>
<tr>
<td align="center">centi</td>
<td align="center">c</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mi mathvariant="normal">/</mi><mn>100</mn></mrow><annotation encoding="application/x-tex">1/100</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1/100</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mrow><mo>−</mo><mn>2</mn></mrow></msup></mrow><annotation encoding="application/x-tex">10^{-2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Centésimo</td>
</tr>
<tr>
<td align="center">mili</td>
<td align="center">m</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mi mathvariant="normal">/</mi><mn>1000</mn></mrow><annotation encoding="application/x-tex">1/1000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1/1000</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mrow><mo>−</mo><mn>3</mn></mrow></msup></mrow><annotation encoding="application/x-tex">10^{-3}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">3</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Milésimo</td>
</tr>
<tr>
<td align="center">micro</td>
<td align="center">μ</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mi mathvariant="normal">/</mi><mn>1000000</mn></mrow><annotation encoding="application/x-tex">1/1000000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1/1000000</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mrow><mo>−</mo><mn>6</mn></mrow></msup></mrow><annotation encoding="application/x-tex">10^{-6}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">6</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Milionésimo</td>
</tr>
<tr>
<td align="center">nano</td>
<td align="center">n</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mi mathvariant="normal">/</mi><mn>1000000000</mn></mrow><annotation encoding="application/x-tex">1/1000000000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1/1000000000</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mrow><mo>−</mo><mn>9</mn></mrow></msup></mrow><annotation encoding="application/x-tex">10^{-9}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">9</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Bilionésimo</td>
</tr>
<tr>
<td align="center">pico</td>
<td align="center">p</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mi mathvariant="normal">/</mi><mn>1000000000000</mn></mrow><annotation encoding="application/x-tex">1/1000000000000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1/1000000000000</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mrow><mo>−</mo><mn>12</mn></mrow></msup></mrow><annotation encoding="application/x-tex">10^{-12}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">12</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Trilionésimo</td>
</tr>
<tr>
<td align="center">femto</td>
<td align="center">f</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mi mathvariant="normal">/</mi><mn>1000000000000000</mn></mrow><annotation encoding="application/x-tex">1/1000000000000000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1/1000000000000000</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mrow><mo>−</mo><mn>15</mn></mrow></msup></mrow><annotation encoding="application/x-tex">10^{-15}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">15</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Quadrilionésimo</td>
</tr>
<tr>
<td align="center">atto</td>
<td align="center">a</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mi mathvariant="normal">/</mi><mn>1000000000000000000</mn></mrow><annotation encoding="application/x-tex">1/1000000000000000000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1/1000000000000000000</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mrow><mo>−</mo><mn>18</mn></mrow></msup></mrow><annotation encoding="application/x-tex">10^{-18}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">18</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Quintilionésimo</td>
</tr>
<tr>
<td align="center">zepto</td>
<td align="center">z</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mi mathvariant="normal">/</mi><mn>1000000000000000000000</mn></mrow><annotation encoding="application/x-tex">1/1000000000000000000000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1/1000000000000000000000</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mrow><mo>−</mo><mn>21</mn></mrow></msup></mrow><annotation encoding="application/x-tex">10^{-21}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">21</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Sextilionésimo</td>
</tr>
<tr>
<td align="center">yocto</td>
<td align="center">y</td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mi mathvariant="normal">/</mi><mn>1000000000000000000000000</mn></mrow><annotation encoding="application/x-tex">1/1000000000000000000000000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1/1000000000000000000000000</span></span></span></span></td>
<td align="center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mrow><mo>−</mo><mn>24</mn></mrow></msup></mrow><annotation encoding="application/x-tex">10^{-24}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">24</span></span></span></span></span></span></span></span></span></span></span></span></td>
<td align="center">Septilionésimo</td>
</tr>
</tbody>
</table>
<h1>Referências</h1>
<p>Prefixos do SI e suas diversas significações: <a href="https://www.facebook.com/PROFCADOSORIO/posts/2336808976461448">https://www.facebook.com/PROFCADOSORIO/posts/2336808976461448</a></p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>cheat-sheet</category>
            <category>curiosities</category>
            <category>SI</category>
            <category>table</category>
            <category>math</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/prefixos-do-si/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Ética no ambiente de trabalho]]></title>
            <link>https://mateusf.com/blog/post/etica-no-ambiente-de-trabalho</link>
            <guid>etica-no-ambiente-de-trabalho</guid>
            <pubDate>Fri, 01 Oct 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Resumo do vídeo "Leandro Karnal fala sobre ética em ambientes profissionais"]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/etica-no-ambiente-de-trabalho/thumbnail" alt=""> # Introdução</p>
<p>Esse é um resumo do vídeo “Leandro Karnal fala sobre ética em ambientes profissionais”, uma entrevista do canal Tribunal Superior do Trabalho ao filósofo Leandro Karnal. O resumo foi realizado para o cumprimento de uma atividade do curso de Logística, da instituição SENAI, e decidi registra-la aqui.</p>
<h1>Ética no ambiente de trabalho</h1>
<p>Primeiramente, oque é a Ética? Ética é o estudo de valores que permitem a convivência harmônica, a busca entre o bom e o belo, a busca da vida politica. Ela rege a capacidade que temos de estabelecer sociabilidade, sociedade, relações, sem a destruição do outro, sem a invasão do espaço do outro, e sem a imposição dos meus valores sobre o outro. Toda ética se baseia no respeito ao espaço do outro, o primeiro passo da ética nos chamamos pequena ética, etiqueta, que se refere a convivência cotidiana com o espaço o outro. Depois a compreensão no ambiente de trabalho, que a hierarquia existe, e que cada um tem suas funções, suas delimitações, e independente da minha posição no organograma do poder, todos são iguais perante a lei e capazes do exercício da convivência.</p>
<p>O ambiente profissional é o ambiente mais claro, onde as pessoas estão sem ter a mesma intimidade familiar, e o mesmo distanciamento da política. É no ambiente de trabalho que exercemos algo acima da afetividade da família, e abaixo do grande distanciamento da política, o grande exercício da ética é no ambiente de trabalho. Já que nos temos a convivência da diversidade, por exemplo, a diversidade de<br>
gêneros, a diversidade de formações, a diversidade de origens sociais, a primeira questão é a do respeito. Então quando utilizo o meu poder ou minha função para exercer algum tipo de invasão do espaço alheio, eu estou quebrando essa ética, ou seja, devemos entender que o ambiente de trabalho não tem a intimidade da família, logo, eu não posso tratar as pessoas como se fossem íntimos familiares. Entender que a diferença entre gênero e hierarquia, são diferenças de serviço. Devemos seguir a regra de ouro da moral e das religiões, “Fazer ao outro o que você quer que faça a você mesmo”.</p>
<p>A todo estante devemos fazer uma reflexão sobre como estamos exercendo a ética, a ética só existe se ela for cultivada como uma capacidade de aperfeiçoamento. Todos nascemos sem ética, todos podemos aprimora-la, por isso é necessário um código de ética, é necessário a atividade do debate, e é necessário a atividade da avaliação da ética. Temos que produzir a sensibilidade ética, que é a sensibilidade ao outro, que fará uma negociação positiva entre o meu bem, e o bem alheio, para a produção do bem comum. A ética rege esses três polos: o eu, o tu, e o nós, e o nós só exste através<br>
do debate, da melhoria e da crítica permanente.</p>
<p>Temos que entender que pode haver demanda, pedido de trabalho, mas que ele nunca passará pela sedução, ou, pelo exercício de poder, que ignore a especificidade da outra pessoa. Devemos pensar em um cargo como um estado momentâneo, ou seja, “eu ESTOU coordenadora”, “eu ESTOU chefe”, “eu ESTOU presidente”, isso significa que temos que lembrar que servimos a outras pessoas, é um exercício de estar, e não de ser, como já citado: “eu ESTOU chefe”, e não “eu SOU chefe”.</p>
<p>Para melhorar o ambiente de trabalho e torna-lo mais saudável e ético devemos, primeiro, criar eventos e trazer debates, entrevistas e questões. Temos que refletir sobre o código de ética atual, temos que demonstrar que o ser humano pode ser aperfeiçoado, que tudo que for próprio do ser humano pode ser transformado e melhorado. É do exercício humano, perfectível, aperfeiçoável, que podemos constantemente produzir algo melhor, por isso, que nos temos pessoas mais éticas, e pessoas menos éticas, porque ética é um esforço pessoal de cultivo diário. Não basta só dizer “agora o tribunal é ético porque tem um código”, é preciso um exercício, constante, diário, cotidiano, e uma meta a ser atingida. Nunca seremos integralmente éticos, mas nos podemos melhorar a partir do ponto que estamos.</p>
<hr>
<h1>Referências</h1>
<p>Leandro Karnal fala sobre ética em ambientes profissionais: <a href="https://www.youtube.com/watch?v=pEXhGE7Fd6s"><em>https://www.youtube.com/watch?v=pEXhGE7Fd6s</em></a></p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>ética</category>
            <category>trabalho</category>
            <category>relacionamento</category>
            <category>convivência</category>
            <category>Leandro Karnal</category>
            <category>filosofia</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/etica-no-ambiente-de-trabalho/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[The GNU Privacy Guard]]></title>
            <link>https://mateusf.com/blog/post/the-gnu-privacy-guard</link>
            <guid>the-gnu-privacy-guard</guid>
            <pubDate>Mon, 30 Aug 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Learning about GPG and your uses]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/the-gnu-privacy-guard/thumbnail" alt=""> # Introdução</p>
<h2>O GPG</h2>
<p>O GPG é um programa de linha de comando que possibilita encriptar mensagens e arquivos usando um sistema de chaves assimétricas. Segundo o site do próprio GPG:</p>
<blockquote>
<p>GnuPG is a complete and free implementation of the OpenPGP standard as defined by <a href="https://www.ietf.org/rfc/rfc4880.txt">RFC4880</a> (also known as<em>PGP</em>). GnuPG allows you to encrypt and sign your data and communications; it features a versatile key management system, along with access modules for all kinds of public key directories. GnuPG, also known as<em>GPG</em>, is a command line tool with features for easy integration with other applications.</p>
</blockquote>
<p>Para entender a diferença de PGP e GPG, veja <a href="https://mfg-b.vercel.app/knowledge/difference-between-pgp-and-gpg">esse artigo</a>.</p>
<p>O GPG usa um sistema de chave publica/privada, que possibilita encriptar mensagens e arquivos, e assinar os mesmos.</p>
<h2>Criptografia assimétrica x simétrica</h2>
<p>Na criptografia simétrica, a chave que usamos para criptografar é a mesma usada para descriptografar. O problema disso, é que a chave precisa ser passada para o destinatário da mensagem criptografada, oque corre o risco de ser interceptada, se tornando inútil a criptografia, visto que o interceptador tem acesso tanto a mensagem quanto a chave que vai descriptografa-la.</p>
<p>Na criptografia assimétrica, a chave que usamos para criptografar será diferente da que usamos para criptografar. Neste caso o destinatário só terá que enviar sua chave pública para o remetente criptografar a mensagem usando a mesma, esta mensagem só poderá ser descriptografada usando a chave privada do destinatário, chave essa que não será enviada na transação, não correndo o risco de ser interceptada.</p>
<h1>Ambiente</h1>
<ul>
<li><strong>OS</strong>: <em>Parrot OS 4.11 x86_64</em></li>
<li><strong>Kernel</strong>: <em>5.10.0-8parrot1-amd64</em></li>
<li><strong>Shell</strong>: <em>ZSH 5.8</em></li>
<li><strong>gpg (GnuPG)</strong>: <em>2.2.27</em></li>
</ul>
<h2>Instalação</h2>
<p>O GnuPG pode ser baixado nesta página: <a href="https://gnupg.org/download/index.html">https://gnupg.org/download/index.html</a></p>
<p>No caso de sistemas baseados em Debian, que usa o gerenciador de pacotes APT, é só rodar o seguinte comando no terminal:</p>
<pre><code class="language-bash">$ sudo apt install gnupg
</code></pre>
<p>Existe também uma lista de front-ends do gpg com interface gráfica no site do GnuPG: <a href="https://www.gnupg.org/software/frontends.html">https://www.gnupg.org/software/frontends.html</a></p>
<h1>Criptografia Simétrica</h1>
<p>O foco da criptografia PGP, é a criptografia assimétrica, mas o GnuPG também tem a opção de criptografar algo usando apenas a criptografia assimétrica.</p>
<h2>Encrypt</h2>
<p>Primeiro vamos criar um arquivo chamado <code>mensagem.txt</code>, com a mensagem "Mensagem super secreta". Nós queremos proteger essa mensagem, para que ninguém que possua a chave possa ter acesso a esta mensagem. Para criptografar a mensagem basta usar a opção <code>--symmetric</code> e o nome do arquivo:</p>
<pre><code class="language-bash">$ gpg --symmetric mensagem.txt
</code></pre>
<p>O software pedirá para que você digite a senha a ser usada, neste caso estou usando a senha <code>123456</code>.</p>
<p>Note que foi criado um arquivo com a extensão <code>.gpg</code> (<code>mensagem.txt.gpg</code>), esse arquivo é o arquivo criptografado, agora é só deletar o arquivo original, e ficar apenas com o arquivo criptografado.</p>
<p><img src="assets/screenshot1.png" alt="/assets/gnupg/screenshot1.png"></p>
<h2>Decrypt</h2>
<p>Para descriptografar a mensagem, usamos o seguinte comando:</p>
<pre><code class="language-bash">$ pgp --output mensagem.txt --decrypt mensagem.txt.gpg
</code></pre>
<p>Opções:</p>
<ul>
<li><code>--output [arquivo]</code>: <em>Define o arquivo de saída a partir do arquivo criptografado.</em></li>
<li><code>--decrypt [arquivo]</code>: <em>Define o arquivo a ser descriptografado.</em></li>
</ul>
<p><img src="assets/screenshot2.png" alt="/assets/gnupg/screenshot2.png"></p>
<h1>Criptografia Assimétrica</h1>
<p>Como já citado, a criptografia assimétrica usa um conceito de chave pública-privada, então para usarmos essa categoria de criptografia precisamos primeiro criar nosso par de chaves (key-pair).</p>
<h2>Criar o key-pair</h2>
<p>Para criar o key-pair basta passar a opção <code>--full-generate-key</code>, sem nenhum outro argumento, o gpg fará uma série de perguntas:</p>
<ol>
<li>O tipo de criptografia a ser usada na hora de gerar as chaves.</li>
<li>O tamanho da chave. Quanto maior a chave mais seguro, mas creio que o padrão recomendado pelo gpg (3072) é o suficiente.</li>
<li>Tempo de duração até a chave expirar. Você tem a opção de expirar a chave em alguns dias, semana, meses, ou anos, ou até sem nenhuma data de expiração. Ai vai da utilidade que terá essa chave.</li>
<li>Ele pede seu nome, email e um comentário, para poder facilitar na identificação do dono da chave. O gpg não verifica a validade de nome e email, então não ha problema em usar informações fictícias. O comentário é exibido ao lado do nome, e pode ser usado para informar um apelido (nickname), ou uma informação adicional sua, ou até pode-se deixar em branco.</li>
<li>Logo após, aparecera uma janela para criar a senha principal da sua chave privada. Escolha uma senha forte.</li>
</ol>
<pre><code class="language-text">$ gpg  --full-generate-key

gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Por favor selecione o tipo de chave desejado:
    (1) RSA and RSA (default)
    (2) DSA and Elgamal
    (3) DSA (apenas assinatura)
    (4) RSA (apenas assinatura)
    (14) Existing key from card
Opção? 1

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072)
O tamanho de chave pedido é 3072 bits

Por favor especifique por quanto tempo a chave deve ser válida.
    0 = chave não expira
    &#x3C;n> = chave expira em n dias
    &#x3C;n>w = chave expira em n semanas
    &#x3C;n>m = chave expira em n meses
    &#x3C;n>y = chave expira em n anos
A chave é valida por? (0) 1
Key expires at sáb 04 set 2021 12:20:51 -03
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Nome completo: Oh tal doh Mattewz
Endereço de correio eletrónico: mateusfg7@email.eu
Comentário: mateusfg7
Você selecionou este identificador de utilizador:
"Oh tal doh Mattewz (mateusfg7) &#x3C;mateusfg7@email.eu>"

Mudar (N)ome, (C)omentário, (E)ndereço ou (O)k/(S)air? O

Precisamos gerar muitos bytes aleatórios. É uma boa ideia realizar outra
actividade (escrever no teclado, mover o rato, usar os discos) durante a
geração dos números primos; isso dá ao gerador de números aleatórios
uma hipótese maior de ganhar entropia suficiente.
Precisamos gerar muitos bytes aleatórios. É uma boa ideia realizar outra
actividade (escrever no teclado, mover o rato, usar os discos) durante a
geração dos números primos; isso dá ao gerador de números aleatórios
uma hipótese maior de ganhar entropia suficiente.

gpg: key 0DA9480F7387D94C marked as ultimately trusted
gpg: revocation certificate stored as '/home/mateusfg7/.gnupg/openpgp-revocs.d/D3EED251C38AE4F4F3EE39310DA9480F7387D94C.rev'
chaves pública e privada criadas e assinadas.

pub   rsa3072 2021-09-03 [SC] [expires: 2021-09-04]
D3EED251C38AE4F4F3EE39310DA9480F7387D94C
uid                      Oh tal doh Mattewz (mateusfg7) &#x3C;mateusfg7@email.eu>
sub   rsa3072 2021-09-03 [E] [expires: 2021-09-04]
</code></pre>
<p><img src="assets/screenshot3.png" alt="/assets/gnupg/screenshot3.png"></p>
<h2>A Chave Pública</h2>
<p>A key-pair já foi gerada e salva no nosso keyring (chaveiro), agora queremos visualizar a nossa chave pública. Primeiro listamos nossas chaves, para isto, usamos a opção <code>--list-key</code>.</p>
<pre><code class="language-text">$ gpg --list-key
</code></pre>
<p><img src="assets/screenshot7.png" alt="/assets/gnupg/screenshot7.png"></p>
<p>Irá aparecer várias chaves, e por último a chave que acabamos de criar. Podemos extrair algumas informações importantes da nossa chave, como:</p>
<ul>
<li>Algorítimo usado e o tamanho da chave: <strong>rsa3072</strong>.</li>
<li>A data de criação da chave: <strong>2021-09-03</strong>.</li>
<li>A data de expiração da chave: <strong>2021-09-04</strong>.</li>
<li>E o fingerprint (digital) da chave: <code>D3EED251C38AE4F4F3EE39310DA9480F7387D94C</code>.<br>
<img src="assets/screenshot8.png" alt="/assets/gnupg/screenshot8.png"></li>
</ul>
<p>É com o fingerprint da chave que usaremos para fazer algumas operações com ela.</p>
<h3>Exportar</h3>
<p>Primeiro precisamos exportar nossa chave para poder compartilhar com outras pessoas. Pediremos o gpg para exportar a chave, usando a opção <code>--export</code>. Também usaremos a opção <code>--armor</code>, para exportar a chave no formato ASCII, sem essa opção a chave será exibida com vários caracteres estranhos.</p>
<p><em>sem a opção <code>--armor</code></em></p>
<p><img src="assets/screenshot5.png" alt="/assets/gnupg/screenshot5.png"></p>
<p><em>com a opção <code>--armor</code></em></p>
<p><img src="assets/screenshot4.png" alt="/assets/gnupg/screenshot4.png"></p>
<p>Essa saída não é muito fácil de decorar, então costumamos a direcionar essa saída para um arquivo. Para isto usamos a opção <code>--output</code>, esse comando por sua vez recebe o nome do arquivo de destino como argumento. Por convenção, criamos esse arquivo com a extensão <code>.pub</code>, de <em>public</em>. Logo após, passaremos o fingerprint da chave que queremos exportar. Nosso comando ficará assim:</p>
<pre><code class="language-text">$ gpg --export --armor --output minha_chave.pub D3EED251C38AE4F4F3EE39310DA9480F7387D94C
</code></pre>
<p><img src="assets/screenshot6.png" alt="/assets/gnupg/screenshot6.png"></p>
<p>É esse arquivo que disponibilizaremos de forma pública.</p>
<h3>Importar</h3>
<p>Para importar uma chave pública para nossa keyring usamos a opção <code>--import</code>, e o arquivo da chave:</p>
<pre><code class="language-text">$ gpg --import minha_chave.pub
</code></pre>
<p><img src="assets/screenshot25.png" alt="/assets/gnupg/screenshot25.png"></p>
<h3>Publicar</h3>
<p>Podemos publicar a nossa chave de forma pública em servidor de chave na internet, para isto basta usar a opção <code>--send-keys</code> e o fingerprint da chave pública que você deseja publicar:</p>
<pre><code class="language-text">$ gpg --send-keys D3EED251C38AE4F4F3EE39310DA9480F7387D94C
</code></pre>
<p>No meu caso minha chave foi enviada para <a href="hkps://keys.openpgp.org">hkps://keys.openpgp.org</a>, se o seu for diferente não tem problema.</p>
<p><img src="assets/screenshot21.png" alt="/assets/gnupg/screenshot21.png"></p>
<p>Para pesquisar uma chave bastar usar a opção <code>--search-keys</code> seguido do fingerprint da chave ou o email da pessoa que você quer pesquisar:</p>
<pre><code class="language-text">gpg --search-keys D3EED251C38AE4F4F3EE39310DA9480F7387D94C
</code></pre>
<p><img src="assets/screenshot22.png" alt="/assets/gnupg/screenshot22.png"></p>
<h3>Editar</h3>
<p>Nós também podemos editar nossa chave. Para isto, usamos a opção <code>--edit-key</code> mais o fingerprint da chave que queremos editar:</p>
<pre><code class="language-text">$ gpg --edit-key D3EED251C38AE4F4F3EE39310DA9480F7387D94C
</code></pre>
<p>Após rodarmos o comando, ira abrir um shell interativo do próprio gpg, com inúmeros comandos e opções para poder editar, para ver todas, basta digitar o comando <code>help</code>.</p>
<p><img src="assets/screenshot9.png" alt="/assets/gnupg/screenshot9.png"><br>
<img src="assets/screenshot10.png" alt="/assets/gnupg/screenshot10.png"></p>
<p>Para exemplificar, mudarei a data de expiração da minha chave para 0, ou seja, vou desativa-la. Após rodar o comando, será pedido o tempo para chave expirar e a senha da chave, para poder realizar as alterações.</p>
<pre><code class="language-text">gpg> expire
Modificar a data de validade para uma chave primária.
Por favor especifique por quanto tempo a chave deve ser válida.
  0 = chave não expira
  &#x3C;n>  = chave expira em n dias
  &#x3C;n>w = chave expira em n semanas
  &#x3C;n>m = chave expira em n meses
  &#x3C;n>y = chave expira em n anos
A chave é valida por? (0) 0
Key does not expire at all
Is this correct? (y/N) y

sec   rsa3072/0DA9480F7387D94C
      created: 2021-09-03  expires: never       usage: SC
      trust: ultimate      validity: ultimate
ssb   rsa3072/A42BFA763F8E415E
      created: 2021-09-03  expires: 2021-09-04  usage: E
[ultimate] (1). Oh tal doh Mattewz (mateusfg7) &#x3C;mateusfg7@email.eu>

gpg: WARNING: Your encryption subkey expires soon.
gpg: You may want to change its expiration date too.
</code></pre>
<p><img src="assets/screenshot11.png" alt="/assets/gnupg/screenshot11.png"></p>
<p>Para salva as alterações e sair do modo interativo, basta digitar <code>quit</code>. Pronto, minha chave agora não tem mais uma data de expiração.</p>
<p><img src="assets/screenshot12.png" alt="/assets/gnupg/screenshot12.png"></p>
<h2>Usando o key-pair</h2>
<h3>Criptografando arquivos</h3>
<p>Para criptografar um arquivo, usamos a opção <code>--encrypt</code>, seguido da opção <code>--recipient</code>, que por sua vez tem como parâmetro o fingerprint de quem receberá a mensagem/arquivo criptografado. Nosso comando final ficará assim:</p>
<pre><code class="language-text">$ gpg --encrypt --recipient 5863874C7BBAFFE7829FB89C4151BFF1C8B0B523 mensagem.txt
</code></pre>
<p><img src="assets/screenshot13.png" alt="/assets/gnupg/screenshot13.png"></p>
<h3>Descriptografando arquivos</h3>
<p>Para descriptografar um arquivo usando a chave privada, basta usar a opção <code>--decrypt</code>, e o arquivo criptografado:</p>
<pre><code class="language-text">$ gpg --decrypt mensagem.txt.gpg
</code></pre>
<p><img src="assets/screenshot14.png" alt="/assets/gnupg/screenshot14.png"></p>
<h3>Assinando mensagens</h3>
<p>Outra função só gpg é assinar mensagens, imagine um cenário em que você não quer esconder a mensagem, e sim certificar que foi você quem escreveu a mesma. Esse é o objetivo de assinar mensagens, a ideia é você usar a chave privada para assinar a mensagem, e alguém que queira validar que aquela assinatura é sua, irá usar a sua chave pública.</p>
<p>Digamos que escrevi algo muito importante para a humanidade, salvei em um arquivo, e quero assinar esse arquivo, para provar que a descoberta foi minha. Para isto assinaremos a mensagem usando a opção <code>--clear-sign</code>, depois usaremos a opção <code>--default-key</code>, com o fingerprint da chave que será usada para assinar a mensagem, e o arquivo a ser assinado:</p>
<pre><code class="language-text">$ gpg --clear-sign --default-key D3EED251C38AE4F4F3EE39310DA9480F7387D94C mensagem.txt
</code></pre>
<p><img src="assets/screenshot15.png" alt="/assets/gnupg/screenshot15.png"></p>
<p>Para verificar a mensagem, basta usar a opção <code>--verify</code>, e o arquivo assinado:</p>
<pre><code class="language-text">$ gpg --verify mensagem.txt.asc
</code></pre>
<p><img src="assets/screenshot16.png" alt="/assets/gnupg/screenshot16.png"></p>
<p>Se alguém alterar a mensagem, a verificação de assinatura irá falhar.</p>
<p><img src="assets/screenshot17.png" alt="/assets/gnupg/screenshot17.png"></p>
<p>Também podemos assinar um arquivo binário, como PDF, imagem, vídeos, executáveis binários, etc. O processo para assinar esse tipo de arquivo será um pouco diferente porque não se abre um arquivo binário para ler, então o gpg criará outro arquivo separado onde contem a assinatura, e para verificarmos se nosso binário é válido, precisamos tanto do arquivo original quanto do arquivo de assinatura. Primeiro criaremos um arquivo binário com dados aleatórios para fins educacionais, mas o processo pode ser feito com qualquer arquivo binário.</p>
<pre><code class="language-text">$ dd if=/dev/zero bs=1000000 count=10 > binary.dat
</code></pre>
<p><img src="assets/screenshot18.png" alt="/assets/gnupg/screenshot18.png"></p>
<p>Para assinarmos arquivos binários usaremos a opção <code>--sign</code>, também usaremos a opção <code>--default-key</code> com o fingerprint da chave que usaremos para assinar o arquivo, e o arquivo:</p>
<pre><code class="language-text">$ gpg --sign --default-key D3EED251C38AE4F4F3EE39310DA9480F7387D94C binary.dat
</code></pre>
<p>Com isso o gpg gerará um outro binário contendo a assinatura do arquivo.</p>
<p><img src="assets/screenshot19.png" alt="/assets/gnupg/screenshot19.png"></p>
<p>Para verificar a assinatura o processo é mesmo citado acima.</p>
<p><img src="assets/screenshot20.png" alt="/assets/gnupg/screenshot20.png"></p>
<h2>Backup</h2>
<p>O backup da chave privada é extremamente importante, pois se você perder o dispositivo onde esta armazenada a chave privada, não há nenhum meio de recupera-la. Para exportar a chave privada, usamos a opção <code>--output</code> seguido do arquivo de saída da chave, depois a opção <code>--export-secret-keys</code> seguido do fingerprint da chave que deseja exportar:</p>
<pre><code class="language-text">$ gpg --output private_key.key  --export-secret-keys D3EED251C38AE4F4F3EE39310DA9480F7387D94C
</code></pre>
<p><img src="assets/screenshot23.png" alt="/assets/gnupg/screenshot23.png"></p>
<p>Para importa-la basta usar a opção <code>--import</code> e o arquivo:</p>
<pre><code class="language-text">$ gpg --import private_key.key
</code></pre>
<p><img src="assets/screenshot24.png" alt="/assets/gnupg/screenshot24.png"></p>
<h1>Conclusão</h1>
<p>Esse foi só um apanhado do básico do GnuPG, há muito mais a se fazer com essa ferramenta. Para conhecer melhor ela basta usar a opção <code>--help</code>, que será listada todas as opções possíveis, ou até, no caso de sistemas Linux, usar o comando <code>man</code> seguido do programa que você quer ver o manual, no caso:</p>
<pre><code class="language-text">$ man gpg
</code></pre>
<p>Isto irá abrir o manual do comando <code>gpg</code>.</p>
<p>Você também pode conferir o site oficial do GnuPG, listado abaixo nas referências.</p>
<hr>
<h1>Referências</h1>
<p>GnuPG: <a href="https://gnupg.org/"><em>https://gnupg.org/</em></a> [<a href="https://web.archive.org/web/20210903075632/https://www.gnupg.org/"><em>archive</em></a>]</p>
<p>Conheça o PGP: mensagens INVIOLÁVEIS com criptografia assimétrica: <a href="https://www.youtube.com/watch?v=p_TYYOtA2LU">https://www.youtube.com/watch?v=p_TYYOtA2LU</a></p>
<p>Tutorial GPG (em português): <a href="https://www.youtube.com/watch?v=r8k-jJ-EHP8">https://www.youtube.com/watch?v=r8k-jJ-EHP8</a></p>
<p>How to Encrypt and Decrypt Files With GPG on Linux: <a href="https://www.howtogeek.com/427982/how-to-encrypt-and-decrypt-files-with-gpg-on-linux/">https://www.howtogeek.com/427982/how-to-encrypt-and-decrypt-files-with-gpg-on-linux/</a> [<a href="https://web.archive.org/web/20210906144246/https://www.howtogeek.com/427982/how-to-encrypt-and-decrypt-files-with-gpg-on-linux/"><em>archive</em></a>]</p>
<p>How to specify private key when decrypting a file using GnuPG?: <a href="https://superuser.com/questions/920793/how-to-specify-private-key-when-decrypting-a-file-using-gnupg">https://superuser.com/questions/920793/how-to-specify-private-key-when-decrypting-a-file-using-gnupg</a> [<a href="https://web.archive.org/web/20210906144523/https://superuser.com/questions/920793/how-to-specify-private-key-when-decrypting-a-file-using-gnupg"><em>archive</em></a>]</p>
<p>Encrypt and sign with specific secret key: <a href="https://unix.stackexchange.com/questions/171715/encrypt-and-sign-with-specific-secret-key">https://unix.stackexchange.com/questions/171715/encrypt-and-sign-with-specific-secret-key</a> [<a href="https://web.archive.org/web/20210906144656/https://unix.stackexchange.com/questions/171715/encrypt-and-sign-with-specific-secret-key"><em>archive</em></a>]</p>
<p>How to create binary file using Bash?: <a href="https://stackoverflow.com/questions/8521240/how-to-create-binary-file-using-bash">https://stackoverflow.com/questions/8521240/how-to-create-binary-file-using-bash</a> [<a href="https://web.archive.org/web/20191109132407/https://stackoverflow.com/questions/8521240/how-to-create-binary-file-using-bash"><em>archive</em></a>]</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>hash</category>
            <category>cryptography</category>
            <category>asymmetric-cipher</category>
            <category>security</category>
            <category>how-to</category>
            <category>pgp</category>
            <category>gpg</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/the-gnu-privacy-guard/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[PGP vs GPG]]></title>
            <link>https://mateusf.com/blog/post/pgp-vs-gpg</link>
            <guid>pgp-vs-gpg</guid>
            <pubDate>Thu, 01 Jul 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[The difference between PGP and GPG]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/pgp-vs-gpg/thumbnail" alt=""> # PGP vs GPG</p>
<p>“PGP” and “GPG” stand for “Pretty Good Privacy” and “Gnu Privacy Guard.” These are two different computer programs developed to protect electronic communications. Today almost everyone uses emails for correspondence and communication, but this medium is not as secure as we think it is. The emails can easily be forged by someone using anybody’s name or identity, and the emails can easily be stored and read by people with special skills. To solve these existing problems and improving the security of emails as well as making them more private, these two programs were developed and used. The privacy of emails is maintained by these programs because they allow encryption of messages by people, and only the people who are authorized can read the encrypted messages; secondly, they are difficult to forge.</p>
<p>For these programs to run properly, the computer used should be secure. If the computers are easily infected with viruses or attacked by spyware programs which can report the key to someone, then first the computer needs to be secure to implement the full strength of these programs.</p>
<h2>PGP</h2>
<p>“PGP” stands for “Pretty Good Privacy.” It was developed by Phil Zimmermann. At first it was written as copyrighted freeware under the Gnu Public License. Later, PGP was upgraded and made into a propriety program. The rights for this program are traded around. The reason for this upgrade was legal defense costs and royalty issues related to the export laws of the USA. Now the PGP program is owned by PGP Corporation. Only the command line version is not owned by PGP Corporation which is also not for sale. PGP uses the RSA algorithm and the IDEA encryption algorithm. The PGP is considered to have Windows interface which is more polished.</p>
<h2>GPG</h2>
<p>“GPG” stands for “Gnu Privacy Guard.” GPG is a re-write or upgrade of PGP. It does not use the IDEA encryption algorithm. This is to make it completely free. It uses the NIST AES, Advanced Encryption Standard. All the algorithm data is stored and documented publicly by OpenPGP Alliance. The main reason for this change is that AES costs less than IDEA and is considered more secure. Moreover, it is royalty free because it is not patented. GPG is more compatible than the original PGP with OpenPGP. GPG is also based on a command line. Windows frontends are also available for GPG other than the command line.</p>
<p>The freeware version of the PGP program can be downloaded from the home page of PGP International. It is restricted for personal use and is not for commercial purposes, or one can buy it from PGP Corporation. The free digital signature and email encryption program can be downloaded from GPG if it is for personal as well as for business use.</p>
<h1>Summary</h1>
<ol>
<li>“PGP” stands for “Pretty Good Privacy”; “GPG” stands for “Gnu Privacy Guard.”</li>
<li>It was the original freeware copyrighted program; GPG is the re-write of PGP.</li>
<li>The PGP uses the RSA algorithm and the IDEA encryption algorithm. GPG uses the NIST AES, Advanced Encryption Standard.</li>
<li>A freeware version of the PGP program can be downloaded from the home page of PGP International. It is restricted for personal use and is not for commercial purposes. The free, digital signature and email encryption program can be downloaded from GPG if it is for personal as well as for business use.</li>
</ol>
<hr>
<h1>referencies</h1>
<p>Difference Between PGP and GPG: <a href="http://www.differencebetween.net/technology/software-technology/difference-between-pgp-and-gpg/">http://www.differencebetween.net/technology/software-technology/difference-between-pgp-and-gpg/</a> [<a href="https://web.archive.org/web/20210701144244/http://www.differencebetween.net/technology/software-technology/difference-between-pgp-and-gpg/"><em>archive</em></a>]</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>hash</category>
            <category>cryptography</category>
            <category>asymmetric-cipher</category>
            <category>security</category>
            <category>archive</category>
            <category>pgp</category>
            <category>gpg</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/pgp-vs-gpg/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Typed Props on Styled Components]]></title>
            <link>https://mateusf.com/blog/post/typed-props-on-styled-components</link>
            <guid>typed-props-on-styled-components</guid>
            <pubDate>Thu, 01 Jul 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Use typed props with styled-compoents and typescript]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/typed-props-on-styled-components/thumbnail" alt=""> # How</p>
<p>Just create a interface and add the type with the property read only. After, add the interface to the tag declaration with <code>&#x3C; ></code>:</p>
<pre><code class="language-typescript">interface Props {
  readonly color: string
}

const Text = styled.h1&#x3C;Props>`
  color: ${(props) => props.color};
`

const Component = () => &#x3C;Text color='white'>Title&#x3C;/Text>

export default Component
</code></pre>
<hr>
<h1>referencies</h1>
<p>Using custom props: <a href="https://styled-components.com/docs/api#using-custom-props">https://styled-components.com/docs/api#using-custom-props</a> [<a href="https://web.archive.org/web/20210701174608if_/https://styled-components.com/docs/api"><em>archive</em></a>]</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>ux/ui</category>
            <category>styles</category>
            <category>typing</category>
            <category>styled-components</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/typed-props-on-styled-components/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Segurança em Linux — Notes]]></title>
            <link>https://mateusf.com/blog/post/seguranca-em-linux-notes</link>
            <guid>seguranca-em-linux-notes</guid>
            <pubDate>Mon, 28 Jun 2021 00:00:00 GMT</pubDate>
            <description><![CDATA["Usem linux… porque no linux não tem vírus?"]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/seguranca-em-linux-notes/thumbnail" alt=""> # Notes</p>
<blockquote>
<p>"Usem linux… porque no linux não tem vírus?"</p>
</blockquote>
<p>Notas baseadas na live "Segurança em Linux — Christiano Linuxman | ROADSEC@HOME#37" da Roadsec, no YouTube.</p>
<h2>Identificação de usuários</h2>
<table>
<thead>
<tr>
<th>usuár.</th>
<th>núme.</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>root</strong></td>
<td><em>0</em></td>
</tr>
<tr>
<td><strong>syst.</strong></td>
<td><em>1 a 999</em></td>
</tr>
<tr>
<td><strong>comum</strong></td>
<td><em>1000 a 65535</em></td>
</tr>
</tbody>
</table>
<h2>Permissões</h2>
<table>
<thead>
<tr>
<th>ação</th>
<th>núme.</th>
</tr>
</thead>
<tbody>
<tr>
<td>read</td>
<td>4</td>
</tr>
<tr>
<td>write</td>
<td>2</td>
</tr>
<tr>
<td>execute</td>
<td>1</td>
</tr>
<tr>
<td><strong>total</strong></td>
<td><strong>7</strong></td>
</tr>
</tbody>
</table>
<h3>Manipulação de arquivos</h3>
<p>Tudo no linux é <strong>arquivo</strong> ou <strong>pasta</strong>. A ordem de permissão de manipular esses arquivos é:</p>
<table>
<thead>
<tr>
<th><strong>dono</strong></th>
<th>.</th>
<th><strong>grupo</strong></th>
<th>.</th>
<th><strong>outras</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>7</strong>(<em>rwx</em>)</td>
<td></td>
<td><strong>7</strong>(<em>rwx</em>)</td>
<td></td>
<td><strong>7</strong>(<em>rwx</em>)</td>
</tr>
</tbody>
</table>
<p>A hierarquia de permissões se da por:</p>
<ul>
<li>Pasta
<ul>
<li>Arquivo</li>
<li>Arquivo</li>
</ul>
</li>
</ul>
<h3>Umask</h3>
<p><code>umask</code> - <strong>user mask</strong> - <em>0 022</em></p>
<p>A <code>umask</code> influencia na permissão de criação de diretórios e arquivos. A <code>umask</code> é um padrão a nível de <em>kernel</em>.</p>
<p>Toda vez que criarmos uma pasta/arquivo, será subtraído a nossa <code>umask</code> (022) da permissão máxima (777), e o resultado será a permissão desta pasta/arquivo.</p>
<p><code>mkdir mateus_pasta</code></p>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>777</mn><mtext>–</mtext><mn>022</mn><mo>=</mo><mn>755</mn></mrow><annotation encoding="application/x-tex">777 – 022 = 755</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">777–022</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">755</span></span></span></span></p>
<p><strong>7</strong><em>rwx</em> <strong>5</strong><em>r-x</em> <strong>5</strong><em>r-x</em></p>
<p><img src="assets/screenshot1.png" alt="/assets/seguranca-em-linux-notes/screenshot1"></p>
<p>No caso do arquivo, será subtraído mais 1 bit de cada permissão (111).</p>
<p><code>touch arquivo</code></p>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>755</mn><mo>−</mo><mn>111</mn><mo>=</mo><mn>644</mn></mrow><annotation encoding="application/x-tex">755 - 111 = 644</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7278em;vertical-align:-0.0833em;"></span><span class="mord">755</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">111</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">644</span></span></span></span></p>
<p><strong>6</strong><em>rw-</em> <strong>4</strong><em>r--</em> <strong>4</strong><em>r--</em></p>
<p><img src="assets/screenshot2.png" alt="/assets/seguranca-em-linux-notes/screenshot2"></p>
<blockquote>
<p>O <code>d</code> junto com as perimções indica que o arquivo é um diretório.</p>
</blockquote>
<h4>Permissões especiais</h4>
<p>Existem também as permissões especiais de usuário, representado pelo primeiro número da <code>umask</code> <em><strong>0</strong>022</em>.</p>
<table>
<thead>
<tr>
<th>permission</th>
<th>n.º</th>
<th>power</th>
</tr>
</thead>
<tbody>
<tr>
<td>SUID BIT</td>
<td>4</td>
<td>rodar binários com o poder de root</td>
</tr>
<tr>
<td>SGID BIT</td>
<td>2</td>
<td>PDC</td>
</tr>
<tr>
<td>STICK BIT</td>
<td>1</td>
<td>define que só quem pode deletar um arquivo é o dono</td>
</tr>
</tbody>
</table>
<p>Imagine o cenário que precisamos que alguém execute o comando <code>shutdown</code>, porem não queremos passar a senha de <em>root</em>. Podemos dar a permissão <em>SUID BIT</em> para o binário <code>shutdown</code>:</p>
<pre><code>$ chmod 4755 /sbin/shutdown
</code></pre>
<p>Assim, qualquer usuário pode executar o comando <code>shutdown</code> com poder de <em>root</em> sem precisar ser <em>root</em>.</p>
<h2>O mito</h2>
<ol>
<li>(<strong>P.</strong>) <em>Arquivos criados pelo usuário têm a permissão 644.</em></li>
<li>(<strong>P.</strong>) <em>Um vírus é um binário com poder de execução.</em></li>
<li>(<strong>1</strong>) <em>Um usuário não pode criar um binário naturalmente.</em></li>
<li>(<strong>2</strong>, <strong>3</strong>) ∴ <em>Sem binários, sem vírus.</em></li>
</ol>
<h2>Manipulando arquivos no lugar certo</h2>
<h3>Libs</h3>
<p>Para cada comando no linux, precisamos de bibliotecas para funcionarem (equivalentes a DLLs do Windows). Então como sei as <em>libs</em> necessárias para rodar um determinado comando? É só usar o comando <code>ldd</code>.</p>
<blockquote>
<p>Ambiente Ubuntu 20.04 no <a href="https://www.katacoda.com/">KataCoda</a></p>
</blockquote>
<pre><code class="language-console">$ which ls
/usr/bin/ls

$ ldd /usr/bin/ls
linux-vdso.so.1 (0x00007ffe4b5fc000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f1e050ec000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1e04efa000)
libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f1e04e6a000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1e04e64000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1e05147000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f1e04e41000)
</code></pre>
<p>Agora executando o comando <code>ldd</code> nos binários <code>cat</code> e <code>wget</code>:</p>
<pre><code class="language-console">$ ldd /bin/cat
linux-vdso.so.1 (0x00007ffeddfd2000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9923dc0000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9923fc9000)

$ ldd /bin/wget
linux-vdso.so.1 (0x00007ffcbd989000)
libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007fbdc6c35000)
libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007fbdc6c2c000)
libidn2.so.0 => /lib/x86_64-linux-gnu/libidn2.so.0 (0x00007fbdc6c0b000)
libssl.so.1.1 => /lib/x86_64-linux-gnu/libssl.so.1.1 (0x00007fbdc6b78000)
libcrypto.so.1.1 => /lib/x86_64-linux-gnu/libcrypto.so.1.1 (0x00007fbdc68a2000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fbdc6886000)
libpsl.so.5 => /lib/x86_64-linux-gnu/libpsl.so.5 (0x00007fbdc6871000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbdc667f000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fbdc665c000)
/lib64/ld-linux-x86-64.so.2 (0x00007fbdc6d5e000)
libunistring.so.2 => /lib/x86_64-linux-gnu/libunistring.so.2 (0x00007fbdc64da000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fbdc64d4000)
</code></pre>
<p>Há uma semelhança notável entre os 3 binários, a biblioteca <code>libc.so.6</code>.</p>
<p><img src="assets/screenshot3.png" alt="/assets/seguranca-em-linux-notes/screenshot3"></p>
<p>A maioria dos comandos linux usam essa biblioteca para funcionarem. Mas se mudarmos o nome desse arquivo e tentarmos executar o <code>ls</code>?</p>
<p><img src="assets/screenshot4.png" alt="/assets/seguranca-em-linux-notes/screenshot4"></p>
<p>O sistema sentou. Bem, para resolver isso é só dar o <code>mv</code> de volta…</p>
<p><img src="assets/screenshot5.png" alt="/assets/seguranca-em-linux-notes/screenshot5"></p>
<h3>Inicialização do Linux</h3>
<p>No linux temos 6 tipos de <em>runlevel</em>, são eles:</p>
<table>
<thead>
<tr>
<th>n.º</th>
<th>command</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>shutdown</td>
</tr>
<tr>
<td>1</td>
<td>modo de segurança</td>
</tr>
<tr>
<td>2</td>
<td>multi-usuário/sem gráfico (debian)</td>
</tr>
<tr>
<td>3</td>
<td>multi-usuário</td>
</tr>
<tr>
<td>4</td>
<td>personalização</td>
</tr>
<tr>
<td>5</td>
<td>multi-usuário/gráfico</td>
</tr>
<tr>
<td>6</td>
<td>reboot</td>
</tr>
</tbody>
</table>
<p>Então se eu souber qual é o primeiro processo, que é o <code>init</code> e chamar o <em>runlevel</em> 0 a máquina irá desligar.</p>
<pre><code class="language-console">$ init 0
</code></pre>
<p>Estamos no <em>level</em> 5, podemos conferir isso rodando o comando <code>runlevel</code>:</p>
<p><img src="assets/screenshot6.png" alt="/assets/seguranca-em-linux-notes/screenshot6"></p>
<p>O N significa que não ouve nenhuma alteração de um <em>runlevel</em> dês da última inicialização. Podemos alterar esses <em>runlevel</em>, e eles estão associados a nossas pastas, se irmos ate a pasta <code>/etc</code> teremos uma pasta para cada <em>runlevel</em>:</p>
<p><img src="assets/screenshot7.png" alt="/assets/seguranca-em-linux-notes/screenshot7"></p>
<p>Na pasta <code>rc5.d</code>, por exemplo, temos alguns processos que não irão subir, iniciador pela letra K (<em>kill</em>), e alguns que irão subir, iniciados pela letra S (<em>start</em>), neste determinado <em>runlevel</em> (5).</p>
<p><img src="assets/screenshot8.png" alt="/assets/seguranca-em-linux-notes/screenshot8"></p>
<p>No arquivo <code>/etc/inittab</code>, na segunda linha temos:</p>
<pre><code>id:5:initdefault
</code></pre>
<p>Oque aconteceria se mudarmos esse número de 5 para 6, e desligarmos, logo após, alguém ligar o PC para navegar na internet? A sequência é:</p>
<p><em><code>id:5:initdefault</code></em></p>
<ul>
<li>Botão Power
<ul>
<li>BIOS/MBR
<ul>
<li>gerenciador de boots (grub2)
<ul>
<li>kernel
<ul>
<li>init
<ul>
<li>DM
<ul>
<li>DE (onde estamos)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><em><code>id:6:initdefault</code></em></p>
<ul>
<li>Botão Power
<ul>
<li>BIOS/MBR
<ul>
<li>gerenciador de boots (grub2)
<ul>
<li>kernel
<ul>
<li>init = 6 (reboot)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>Caímos em um loop.</p>
<h2>Privilege Escalation</h2>
<p>Vamos tentar fazer um ataque de <em>privilege escalation</em> em um Linux, usando as permissões como área de exploração.</p>
<p>Primeiro vamos pesquisar na raiz do sistema, todo arquivo que tenha a permissão 4000, com o comando <code>find / -perm -4000 2>/dev/null</code>:</p>
<p><img src="assets/screenshot9.png" alt="/assets/seguranca-em-linux-notes/screenshot9"></p>
<p>Obteremos vários resultados úteis, mas o que queremos é o <em>cpulimit</em>:</p>
<p><img src="assets/screenshot10.png" alt="/assets/seguranca-em-linux-notes/screenshot10"></p>
<p>O <em>cpulimit</em> tem a permissão <em>SUID BIT</em>, ou seja, quando executa-lo ele irá trabalhar como root. Sendo assim, podemos criar uma pasta na raiz executando o comando <code>cpulimit -l 100 -r mkdir /pasta</code>, mesmo como um usuário comum:</p>
<p><img src="assets/screenshot11.png" alt="/assets/seguranca-em-linux-notes/screenshot11"></p>
<p>Bem, se podemos executar um binário como root, e se usarmos isso para dar permissão <em>SUID BIT</em> também no binário <code>bash</code>?</p>
<p><img src="assets/screenshot12.png" alt="/assets/seguranca-em-linux-notes/screenshot12"></p>
<ol>
<li>Dou permissão SUID BIT para o binário bash</li>
</ol>
<pre><code class="language-console">$ cpulimit -l 100 -f chmod 4755 /usr/bin/bash
</code></pre>
<hr>
<h1>referências</h1>
<p>Segurança em Linux - Christiano Linuxman | ROADSEC@HOME#37: <a href="https://www.youtube.com/watch?v=AzB5BNDTXOk"><em>https://www.youtube.com/watch?v=AzB5BNDTXOk</em></a></p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>security</category>
            <category>roadsec</category>
            <category>linux</category>
            <category>permissions</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/seguranca-em-linux-notes/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Python Subprocess]]></title>
            <link>https://mateusf.com/blog/post/python-subprocess</link>
            <guid>python-subprocess</guid>
            <pubDate>Fri, 11 Jun 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Understanding the subprocess lib and their use cases]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/python-subprocess/thumbnail" alt=""> # Introduction</p>
<p>A subprocess is OS process that runs inside of another process father. The <code>subprocess</code> module allows to run subprocess with Python.</p>
<p>We can use <code>subprocess</code> to run shell commands in a better way than <code>os.system</code> module.</p>
<h1>Execute a command</h1>
<p>Now, we can just run a command to see the files in the current folder. In Linux we will run the <code>ls</code> command, like this:</p>
<p><img src="assets/screenshot_1.png" alt="/assets/python-subprocess/screenshot_1"></p>
<p><em>The <code>-l</code> option is to show the details of the files.</em></p>
<p>To run this with <code>subprocess</code> we need to run the <code>call()</code> function. The first param of the function is an list, with the command, where each value of the list is an option of the command:</p>
<pre><code class="language-python">subprocess.call(['ls', '-l'])
</code></pre>
<p><em>Otherwise we can use a simple string. e.g.: <code>'ls -l'</code></em></p>
<p><img src="assets/screenshot_2.png" alt="/assets/python-subprocess/screenshot_2"></p>
<h1>Check command output</h1>
<p>To check the output of the command we will use the function <code>check_call()</code>. Why not use <code>call()</code>, again? If occurs an error in the command execute, the <code>call()</code> will just show the error, without the possibility of handling this error. The same not occurs with <code>check_call()</code>, we can get the error, and handling it.</p>
<pre><code class="language-python">import subprocess

try:
    subprocess.check_call(['cat', 'file_1.py'])
except Exception as E:
    print(E)
</code></pre>
<p><img src="assets/screenshot_3.png" alt="/assets/python-subprocess/screenshot_3"></p>
<h1>Get the command output</h1>
<p>To save the output of the command in a variable, we will use <code>check_output()</code>.</p>
<pre><code class="language-python">import subprocess

o = subprocess.check_output(['cat', 'file_1.py'])

print("Output:", o)
</code></pre>
<p><img src="assets/screenshot_4.png" alt="/assets/python-subprocess/screenshot_4"></p>
<h1>Popen: icing on the cake</h1>
<p>The function <code>Popen</code> is like <code>call()</code>, but their return an object with several object to handler the output, error, etc.</p>
<p>Lets run a python program:</p>
<pre><code class="language-python">subprocess.Popen('python3 file_1.py', stdout=subprocess.PIPE, shell=True).stdout.read()
</code></pre>
<p>The <code>stdout=subprocess.PIPE</code> param defines that the output of the subprocess is not the terminal, but the own process. The <code>shell=True</code> defines that the process will run in the own command line.</p>
<p>We are getting the <code>stdout</code> object of <code>Popen</code>, and running the <code>read()</code> function to read the output of the command.</p>
<hr>
<h1>referencies</h1>
<p>Aulas Python - 114 - Ferramentas de Sistema X: Módulo subprocess: <a href="https://www.youtube.com/watch?v=jgmIUa2_wSY">https://www.youtube.com/watch?v=jgmIUa2_wSY</a></p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>library</category>
            <category>subprocess</category>
            <category>process</category>
            <category>cli</category>
            <category>python</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/python-subprocess/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Self-Host Softwares List]]></title>
            <link>https://mateusf.com/blog/post/self-host-softwares-list</link>
            <guid>self-host-softwares-list</guid>
            <pubDate>Tue, 25 May 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[A list with some self-host softwares]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/self-host-softwares-list/thumbnail" alt=""> # Introduction</p>
<p>Self-Host softwares is the softwares that you can upload an instance on your own web server, gaining control and privacy, without depending on third parties.</p>
<p>It is highly recommended to upload instances in a <a href="https://www.docker.com/">docker</a> container.</p>
<h1>Softwares</h1>
<h2>Storage</h2>
<blockquote>
<p>Alternatives to: Dropbox, Mega, Google Drive, OneDrive, Mediafire...</p>
</blockquote>
<p><a href="https://nextcloud.com/"><strong>Nextcloud</strong></a>: <em>Nextcloud is a suite of client-server software for creating and using file hosting services. It is enterprise-ready with comprehensive support options. Being free and open-source software, anyone is allowed to install and operate it on their own private server devices.</em></p>
<p><a href="https://www.tahoe-lafs.org/trac/tahoe-lafs"><strong>Tahoe-LAFS</strong></a>: <em>Tahoe-LAFS is a Free and Open decentralized cloud storage system. It distributes your data across multiple servers. Even if some of the servers fail or are taken over by an attacker, the entire file store continues to function correctly, preserving your privacy and security.</em></p>
<p><a href="https://www.tonido.com/"><strong>Tonido</strong></a>: <em>Tonido Server allows you to access all your files on your computer from a web browser, smartphone, tablet or even DLNA enabled devices. Easy to get started: just install the Tonido Server software and your computer turns into a private cloud server. Easy to remember link to your computer. e.g.: <a href="http://john.tonidoID.com">http://john.tonidoID.com</a>.</em></p>
<p><a href="https://owncloud.com/"><strong>ownCloud</strong></a>: <em>Access, Sync and Share Your Data, Under Your Control! ownCloud is a self-hosted file sync and share server. It provides access to your data through a web interface, sync clients or WebDAV while providing a platform to view, sync and share across devices easily — all under your control. ownCloud’s open architecture is extensible via a simple but powerful API for applications and plugins and it works with any storage.</em></p>
<p><a href="https://www.resilio.com/"><strong>Resilio Sync &#x26; Sync Pro (Personal)</strong></a>: <em>A fast, reliable, and simple file sync and share solution. Sync any folder to all your devices. Sync photos, videos, music, PDFs, docs or any other file types to/from your mobile phone, laptop, or NAS. Build your own private cloud and create a private cloud that is securely distributed across devices you own. Your cloud is much faster than the public cloud. It is also much safer – no one can steal your data from the cloud if your data is not in the cloud.</em></p>
<p><a href="https://syncthing.net/"><strong>Syncthing</strong></a>: <em>Syncthing replaces proprietary sync and cloud services with something open, trustworthy and decentralized. Your data is your data alone and you deserve to choose where it is stored, if it is shared with some third party and how it’s transmitted over the Internet.</em></p>
<p><a href="https://cozy.io/en/"><strong>Cozy</strong></a>: <em>Store, sync, and share your data just the way you want it. Run your cloud at home. Enjoy better storage and keep your data private. Cozy is a versatile and extensible platform that can be put to a variety of practical uses: from sharing your photos with friends and family to contacts and schedule management. More importantly, Cozy can be hosted on your own physical or virtual server.</em></p>
<h2>Share</h2>
<p><a href="https://github.com/RobinLinus/snapdrop"><strong>Snapdrop</strong></a>: <em>Local file sharing in your browser. Inspired by Apple's Airdrop.</em></p>
<h2>Media</h2>
<blockquote>
<p>Alternative to: Netflix, Youtube, Spotify, Google Photos...</p>
</blockquote>
<p><a href="https://emby.media/"><strong>Emby</strong></a>: <em>Bringing all of your home videos, music, and photos together into one place has never been easier. Your personal Emby Server automatically converts and streams your media on-the-fly to play on any device.</em></p>
<p><a href="https://jellyfin.org/"><strong>Jellyfin</strong></a>: <em>Jellyfin is the volunteer-built media solution that puts you in control of your media. Stream to any device from your own server, with no strings attached. Your media, your server, your way.</em></p>
<p><a href="https://joinpeertube.org/"><strong>PeerTube</strong></a>: <em>PeerTube, developed by Framasoft, is the free and decentralized alternative to video platforms, providing you over 400,000 videos published by 60,000 users and viewed over 15 million times</em></p>
<p><a href="https://github.com/navidrome/navidrome"><strong>navidrome</strong></a>: <em>Navidrome is an open source web-based music collection server and streamer. It gives you freedom to listen to your music collection from any browser or mobile device. It's like your personal Spotify!</em></p>
<p><a href="https://lidarr.audio/"><strong>Lidarr</strong></a>: <em>Lidarr is a music collection manager for Usenet and BitTorrent users. It can monitor multiple RSS feeds for new albums from your favorite artists and will interface with clients and indexers to grab, sort, and rename them. It can also be configured to automatically upgrade the quality of existing files in the library when a better quality format becomes available.</em></p>
<p><a href="https://github.com/photoprism/photoprism"><strong>PhotoPrism</strong></a>: <em>PhotoPrism® is a privately hosted app for browsing, organizing, and sharing your photo collection. It makes use of the latest technologies to tag and find pictures automatically without getting in your way. Say goodbye to solutions that force you to upload your visual memories to the cloud!</em></p>
<p><a href="https://tdarr.io"><strong>Tdarr</strong></a>: <em>Tdarr V2 is a cross-platform, distributed transcoding system which is broken up into multiple modules. Getting multiple machines working together across a local network requires some configuration.</em></p>
<h2>Social</h2>
<p><a href="https://element.io/"><strong>Element</strong></a>: <em>Element is a messenger that gives you the privacy you expect from a conversation in your own home, but with everyone across the globe.</em></p>
<p><a href="https://rocket.chat/"><strong>Rocket.chat</strong></a>: <em>Keep the workflow going by centralizing all your tools and touchpoints in one platform. Made for team<br>
collaboration, DevOps and customer engagement.</em></p>
<h2>Remote Controll</h2>
<p><a href="https://guacamole.apache.org/"><strong>Apache Guacamole</strong></a>: <em>Apache Guacamole is a clientless remote desktop gateway. It supports standard protocols like VNC, RDP, and SSH. We call it clientless because no plugins or client software are required. Thanks to HTML5, once Guacamole is installed on a server, all you need to access your desktops is a web browser.</em></p>
<h2>Library</h2>
<p><a href="https://gitlab.com/LazyLibrarian/LazyLibrarian"><strong>LazyLibrarian</strong></a>: <em>LazyLibrarian is a SickBeard, CouchPotato, Headphones-like application for ebooks, audiobooks and magazines.</em></p>
<p><a href="https://www.bookstackapp.com/"><strong>BookStack</strong></a>: <em>BookStack is a simple, self-hosted, easy-to-use platform for organising and storing information.</em></p>
<p><a href="https://js.wiki/"><strong>Wiki.js</strong></a>: <em>Make documentation a joy to write using Wiki.js's beautiful and intuitive interface!</em></p>
<h2>Feed Agregator</h2>
<blockquote>
<p>Alternative to: Pocket, Feedly...</p>
</blockquote>
<p><a href="https://github.com/wallabag/wallabag"><strong>wallabag</strong></a>: <em>wallabag is a self hostable application for saving web pages: Save and classify articles. Read them later. Freely.</em></p>
<p><a href="https://freshrss.org/"><strong>FreshRSS</strong></a>: <em>A free, self-hostable aggregator.</em></p>
<h2>Download</h2>
<p><a href="https://www.qbittorrent.org/"><strong>qBittorrent</strong></a>: <em>The qBittorrent project aims to provide an open-source software alternative to µTorrent.</em></p>
<p><a href="https://deluge-torrent.org/"><strong>Deluge</strong></a>: <em>Deluge is a lightweight, Free Software, cross-platform BitTorrent client.</em></p>
<p><a href="https://pyload.net/"><strong>pyLoad</strong></a>: <em>Free and Open Source download manager written in Python and designed to be extremely lightweight, easily extensible and fully manageable via web.</em></p>
<h2>Security</h2>
<p><a href="https://github.com/dani-garcia/vaultwarden"><strong>VaultWarden</strong></a>: <em>Alternative implementation of the Bitwarden server API written in Rust and compatible with upstream Bitwarden clients*, perfect for self-hosted deployment where running the official resource-heavy service might not be ideal.</em></p>
<p><a href="https://www.vaultproject.io/"><strong>Vault</strong></a>: <em>Secure, store and tightly control access to tokens, passwords, certificates, encryption keys for protecting secrets and other sensitive data using a UI, CLI, or HTTP API.</em></p>
<p><a href="https://github.com/bitwarden/server"><strong>Bitwarden</strong></a>: <em>Open source password management solutions for individuals, teams, and business organizations.</em></p>
<h2>Web Search</h2>
<blockquote>
<p>Alternative to: Google, DuckDuckGo, Bing...</p>
</blockquote>
<p><a href="https://github.com/searx/searx"><strong>searx</strong></a>: <em>Privacy-respecting metasearch engine.</em></p>
<h2>Office</h2>
<p><a href="https://www.onlyoffice.com/"><strong>OnlyOffice</strong></a>: <em>OnlyOffice, stylized as ONLYOFFICE, is a free software office suite developed by Ascensio System SIA, a company headquartered in Riga, Latvia. It features online document editors, platform for document management, corporate communication, mail and project management tools.</em></p>
<p><a href="https://www.cups.org/"><strong>CUPS</strong></a>: <em>CUPS is the standards-based, open source printing system developed by Apple Inc. for macOS® and other UNIX®-like operating systems. CUPS uses the Internet Printing Protocol (IPP) to support printing to local and network printers.</em></p>
<p><a href="https://leantime.io/"><strong>LeanTime</strong></a>: <em>Straightforward open source project management system to make your ideas reality.</em></p>
<h2>Code</h2>
<p><a href="https://gitea.io/en-us/"><strong>Gitea</strong></a>: <em>Gitea is an open-source forge software package for hosting software development version control using Git as well as other collaborative features like bug tracking, wikis and code review. It supports self-hosting but also provides a free public first-party instance hosted in China on DiDi's cloud. It is a fork of Gogs and is written in Go. Gitea can be hosted on all platforms supported by Go including Linux, macOS, and Windows. The project is funded on Open Collective.</em></p>
<p><a href="https://bitbucket.org/product/enterprise"><strong>Bitbucket</strong></a>: <em>Bitbucket Data Center is a self-managed solution that provides source code collaboration for professional teams of any size, across any distance</em></p>
<p><a href="https://github.com/cdr/code-server"><strong>code-server</strong></a>: <em>Run VS Code on any machine anywhere and access it in the browser.</em></p>
<p><a href="https://www.jenkins.io/"><strong>Jenkins</strong></a>: <em>The leading open source automation server, Jenkins provides hundreds of plugins to support building, deploying and automating any project.</em></p>
<p><a href="https://jupyter.org/"><strong>Jupyter</strong></a>: <em>JupyterLab is a web-based interactive development environment for Jupyter notebooks, code, and data. JupyterLab is flexible: configure and arrange the user interface to support a wide range of workflows in data science, scientific computing, and machine learning. JupyterLab is extensible and modular: write plugins that add new components and integrate with existing ones.</em></p>
<h2>Home Automation</h2>
<p><a href="https://github.com/home-assistant/core"><strong>home-assistent</strong></a>: <em>Open source home automation that puts local control and privacy first. Powered by a worldwide community of tinkerers and DIY enthusiasts. Perfect to run on a Raspberry Pi or a local server.</em></p>
<p><a href="https://homebridge.io/"><strong>Home Bridge</strong></a>: <em>Homebridge allows you to integrate with smart home devices that do not natively support HomeKit. There are over 2,000 Homebridge plugins supporting thousands of different smart accessories.</em></p>
<h2>Finance</h2>
<p><a href="https://www.firefly-iii.org/"><strong>Firely</strong></a>: <em>A free and open source personal finance manager.</em></p>
<h2>Router</h2>
<p><a href="https://opnsense.org/"><strong>OPNSense</strong></a>: <em>From Virtual Private Networking to Intrusion Detection, Best in class, FREE Open Source Project.</em></p>
<p><a href="https://www.pfsense.org/"><strong>pfSense</strong></a>: <em>pfSense is a firewall/router computer software distribution based on FreeBSD. pfSense Community Edition (CE) is the partially open source version while pfSense Plus has moved to a closed source model. It is installed on a physical computer or a virtual machine to make a dedicated firewall/router for a network. It can be configured and upgraded through a web-based interface, and requires no knowledge of the underlying FreeBSD system to manage.</em></p>
<p><a href="https://github.com/IAmStoxe/wirehole"><strong>wirehole</strong></a>: <em>WireHole is a combination of WireGuard, Pi-hole, and Unbound in a docker-compose project with the intent of enabling users to quickly and easily create a personally managed full or split-tunnel WireGuard VPN with ad blocking capabilities thanks to Pi-hole, and DNS caching, additional privacy options, and upstream providers via Unbound.</em></p>
<p><a href="https://netbox.readthedocs.io/en/stable/"><strong>NetBox</strong></a>: <em>NetBox is an open source web application designed to help manage and document computer networks. Initially conceived by the network engineering team at DigitalOcean, NetBox was developed specifically to address the needs of network and infrastructure engineers.</em></p>
<h2>Networks</h2>
<blockquote>
<p>Alternative to conventional, centralized, internet.</p>
</blockquote>
<p><a href="https://zeronet.io/"><strong>ZeroNet</strong></a>: <em>Open, free and uncensorable websites,<br>
using Bitcoin cryptography and BitTorrent network.</em></p>
<h2>Stats</h2>
<p><a href="https://grafana.com/"><strong>Grafana</strong></a>: <em>Grafana® allows you to query, visualize, alert on and understand your metrics no matter where they are stored. Create, explore, and share dashboards with your team and foster a data driven culture.</em></p>
<p><a href="https://icinga.com/"><strong>Icinga</strong></a>: <em>Monitor Your Entire Infrastructure. Find answers, take actions and become a problem-solver. Be flexible and take your own ways. Stay curious, stay passionate, stay in the loop. Tackle your monitoring challenge.</em></p>
<h2>Container Manager</h2>
<p><a href="https://www.portainer.io/"><strong>Porteiner</strong></a>: <em>Portainer is a universal container management tool. It works with Kubernetes, Docker, Docker Swarm and Azure ACI. It allows you to manage containers without needing to know platform-specific code.</em></p>
<p><a href="https://kubernetes.io/"><strong>Kubernets</strong></a>: <em>Kubernetes, also known as K8s, is an open-source system for automating deployment, scaling, and management of containerized applications.</em></p>
<h1>Conclusion</h1>
<p>Help me with this list!</p>
<p>If you know more softwares, make a contribution to the list at <a href="https://github.com/mateusfg7/mfg-b/blob/main/_posts/self-hosted-softwares.md">https://github.com/mateusfg7/mfg-b/blob/main/_posts/self-hosted-softwares.md</a></p>
<h1>referencies</h1>
<ul>
<li><a href="https://privacytools.io/">https://privacytools.io/</a> [<a href="https://web.archive.org/web/20210922131626/https://privacytools.io/"><em>archive</em></a>]</li>
<li><a href="https://privacytools.io/software/cloud/">https://privacytools.io/software/cloud/</a> [<a href="https://web.archive.org/web/20210922131749/https://privacytools.io/software/cloud/"><em>archive</em></a>]</li>
<li><a href="https://privacytools.io/software/networks/">https://privacytools.io/software/networks/</a> [<a href="https://web.archive.org/web/20210922131730/https://privacytools.io/software/networks/"><em>archive</em></a>]</li>
<li><a href="https://privacytools.io/software/real-time-communication/">https://privacytools.io/software/real-time-communication/</a> [<a href="https://web.archive.org/web/20210922131742/https://privacytools.io/software/real-time-communication/"><em>archive</em></a>]</li>
<li><a href="https://privacytools.io/software/passwords/">https://privacytools.io/software/passwords/</a> [<a href="https://web.archive.org/web/20210922131748/https://privacytools.io/software/passwords/"><em>archive</em></a>]</li>
<li><a href="https://www.geckoandfly.com/24024/self-hosted-cloud-storage/">https://www.geckoandfly.com/24024/self-hosted-cloud-storage/</a> [<a href="https://web.archive.org/web/20210629145200/https://www.geckoandfly.com/24024/self-hosted-cloud-storage/"><em>archive</em></a>]</li>
<li><a href="https://www.reddit.com/r/selfhosted/">https://www.reddit.com/r/selfhosted/</a> [<a href="https://web.archive.org/web/20210916142932/https://www.reddit.com/r/selfhosted/"><em>archive</em></a>]</li>
<li><a href="https://www.reddit.com/r/selfhosted/comments/nfkeju/organizr_to_heimdall_to_sui_and_now_homer_my/">https://www.reddit.com/r/selfhosted/comments/nfkeju/organizr_to_heimdall_to_sui_and_now_homer_my/</a> [<a href="https://web.archive.org/web/20210518195440/https://www.reddit.com/r/selfhosted/comments/nfkeju/organizr_to_heimdall_to_sui_and_now_homer_my/"><em>archive</em></a>]</li>
<li><a href="https://www.reddit.com/r/selfhosted/comments/nhlzww/my_dashboard_2021_edition_i_love_self_hosting/">https://www.reddit.com/r/selfhosted/comments/nhlzww/my_dashboard_2021_edition_i_love_self_hosting/</a> [<a href="https://web.archive.org/web/20210610021807/https://www.reddit.com/r/selfhosted/comments/nhlzww/my_dashboard_2021_edition_i_love_self_hosting/"><em>archive</em></a>]</li>
</ul>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>server</category>
            <category>self-host</category>
            <category>devops</category>
            <category>tools</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/self-host-softwares-list/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[NLW#5 - React Native Notes]]></title>
            <link>https://mateusf.com/blog/post/nlw5-react-native-notes</link>
            <guid>nlw5-react-native-notes</guid>
            <pubDate>Tue, 11 May 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[React Native notes write during NextLevelWeek]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/nlw5-react-native-notes/thumbnail" alt=""> # Packages</p>
<p>To install a package with expo just type:</p>
<pre><code>$ expo install [package]
</code></pre>
<h2>Used Packages/Components</h2>
<ul>
<li>
<p><strong>react-native</strong> (does not need installation)</p>
<ul>
<li><strong>SafeAreaView</strong>: <em>A view, but contain all the content in visible area of the phone. (just works on Iphone)</em></li>
<li><strong>Platform</strong>: <em>Get information about the running device.</em></li>
<li><strong>StatusBar</strong>: <em>Get information and dimensions about the status bar of the phone.</em></li>
<li><strong>Dimensions</strong>: <em>Get dimensions of the phone.</em></li>
<li><strong>KeyboardAvoidingView</strong>: <em>A view that modify the elements position when the keyboard is open.</em></li>
<li><strong>FlatList</strong>: <em>Component to create a list of items, something like <code>map()</code> of Javascript.</em></li>
<li><strong>ActivityIndicator</strong>: <em>Component to show load circle</em></li>
</ul>
</li>
<li>
<p><strong>expo</strong></p>
<ul>
<li><strong>@expo/vector-icons</strong>: <em>Use most common icons on expo, equivalent to react-icons package for React.</em></li>
<li><strong>expo-font</strong>: <em>Use customized fonts on expo.</em></li>
<li><strong>@expo-google-fonts/[font]</strong>: <em>Use a specific font from google fonts. package e.g.: @expo-google-fonts/inter</em></li>
<li><strong>expo-app-loading</strong>: <em>The splash screen as a component</em></li>
<li><strong>lottie-react-native</strong>: <em>Use animation on expo/react-native</em></li>
</ul>
</li>
<li>
<p><strong>misc</strong>:</p>
<ul>
<li><strong>RectButton</strong> from <strong>react-native-gesture-handler</strong>: <em>Button component with native press style. Types: <strong>RectButtonProps</strong>.</em></li>
<li><strong>Swipeable</strong> from <strong>react-native-gesture-handler/Swipeable</strong>: <em>A view thats allows swipe it to any side, and render some component behind original component</em></li>
<li><strong>react-native-iphone-x-helper</strong>: <em>Misc help methods for Iphone X</em></li>
</ul>
</li>
</ul>
<h1>Javascript/Typescript</h1>
<h2>If/Else</h2>
<p>The <code>if</code> conditional accepts a block without <code>{}</code>, like:</p>
<pre><code class="language-typescript">if (condition) return 'Hello Word'

if (condition) return 'Hello Word'
</code></pre>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>nlw5</category>
            <category>rocketseat</category>
            <category>mobile</category>
            <category>expo</category>
            <category>libs</category>
            <category>react-native</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/nlw5-react-native-notes/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[NLW#5 - React Notes]]></title>
            <link>https://mateusf.com/blog/post/nlw5-react-notes</link>
            <guid>nlw5-react-notes</guid>
            <pubDate>Tue, 04 May 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[React notes write during NextLevelWeek #5 of the Rocketseat]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/nlw5-react-notes/thumbnail" alt=""> # CSS</p>
<h2>Y-Scroll just to a component</h2>
<p><em>You need to set a fixed height</em></p>
<pre><code class="language-css">.component {
  height: 100vh;
  overflow-y: scroll;
}
</code></pre>
<h2>Use "..." when the text exceed component width</h2>
<pre><code class="language-css">.component {
  text-overflow: ellipsis;
}
</code></pre>
<h1>JS</h1>
<h2>Ternary If/Else</h2>
<pre><code class="language-js">a = 1
b = 2

c = a == 1 ? a : b
</code></pre>
<p><em>without "else"</em></p>
<pre><code class="language-js">a = 1
b = 2

c = a == 1 &#x26;&#x26; a
</code></pre>
<p><em>just the "else"</em></p>
<pre><code class="language-js">a = 1
b = 2

c = a != 1 || b
</code></pre>
<hr>
<h1>referencies</h1>
<p>Rocketseat: <a href="https://rocketseat.com.br/"><em>https://rocketseat.com.br/</em></a></p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>nlw5</category>
            <category>rocketseat</category>
            <category>web</category>
            <category>ssr</category>
            <category>ssg</category>
            <category>tips</category>
            <category>next.js</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/nlw5-react-notes/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[NLW#5 - Elixir Notes]]></title>
            <link>https://mateusf.com/blog/post/nlw5-elixir-notes</link>
            <guid>nlw5-elixir-notes</guid>
            <pubDate>Mon, 26 Apr 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Elixir notes write during NextLevelWeek #5 of the Rocketseat]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/nlw5-elixir-notes/thumbnail" alt=""> # Notes</p>
<h2>Commands</h2>
<h3>Create new API project:</h3>
<pre><code class="language-bash">$ mix phx.new project-name --no-html --no-webpack
</code></pre>
<h3>Create database:</h3>
<p><em>with database online</em></p>
<pre><code class="language-bash">$ mix ecto.create
</code></pre>
<h3>Install dependencies:</h3>
<pre><code class="language-bash">$ mix deps.get
</code></pre>
<h3>Create config file for credo:</h3>
<pre><code class="language-bash">$ mix credo.gen.config
</code></pre>
<h3>Create a migration</h3>
<pre><code class="language-bash">$ mix ecto.gen.migration migration_name
</code></pre>
<h3>Run migrations</h3>
<pre><code class="language-bash">$ mix ecto.migrate
</code></pre>
<h2>Elixir</h2>
<h3>Manipulate maps</h3>
<pre><code class="language-elixir">map = %{a: 1, b: 2}
IO.puts map[:a]

map2 = %{"a" => 1, "b" => 1}
IO.puts map["a"]
</code></pre>
<p>we can use <code>Map.get/2</code> to get the value</p>
<pre><code class="language-elixir">iex> map = %{"a" => 1, "b" => 1}
iex> Map.get(map, "a")
1
</code></pre>
<p>we can use <code>Map.get/3</code> to get the value of a index, or a default value</p>
<pre><code class="language-elixir">iex> map = %{"a" => 1, "b" => 1}
iex> map["name"]
nil
iex> Map.get(map, "name")
nil
iex> Map.get(map, "name", 5)
5
</code></pre>
<h2>Phoenix</h2>
<h3>Use UUID as primary key</h3>
<p>On <code>config/config.exs</code> add the config:</p>
<pre><code class="language-elixir">config :project, Project.Repo,
  migration_primary_key: [type: :binary_id],
  migration_foreign_key: [type: :binary_id]
</code></pre>
<h3>Use resources to create default routes of a controller</h3>
<p>On <code>lib/project_web/router.ex</code>:</p>
<pre><code class="language-elixir">scope "/api", ProjectWeb do
  pipe_through :api

  resources "/some-route", SomeController
end
</code></pre>
<p>This will create all default route for SomeController, running <code>mix phx.routes</code> we will get:</p>
<pre><code>some_path  GET     /api/some-route           ProjectWeb.SomeController :index
some_path  GET     /api/some-route/:id/edit  ProjectWeb.SomeController :edit
some_path  GET     /api/some-route/new       ProjectWeb.SomeController :new
some_path  GET     /api/some-route/:id       ProjectWeb.SomeController :show
some_path  POST    /api/some-route           ProjectWeb.SomeController :create
some_path  PATCH   /api/some-route/:id       ProjectWeb.SomeController :update
           PUT     /api/some-route/:id       ProjectWeb.SomeController :update
some_path  DELETE  /api/some-route/:id       ProjectWeb.SomeController :delete
</code></pre>
<p>We can pass the parameter <code>only</code> to specify the methods:</p>
<pre><code class="language-elixir">scope "/api", ProjectWeb do
  pipe_through :api

  resources "/some-route", SomeController, only: [:create, :show]
end
</code></pre>
<h2>Bamboo</h2>
<p>First add bamboo to deps on <code>mix.ex</code>:</p>
<pre><code class="language-elixir">defp deps do
  [
    {:bamboo, "~> 2.1.0"}
  ]
end
</code></pre>
<h3>Use Local Adapter</h3>
<p>On <code>config/config.exs</code> add:</p>
<pre><code class="language-elixir">config :inmana, Inmana.Mailer, adapter: Bamboo.LocalAdapter
</code></pre>
<p>to use in teste, add the config on <code>config/test.exs</code>:</p>
<pre><code class="language-elixir">config :inmana, Inmana.Mailer, adapter: Bamboo.TestAdapter
</code></pre>
<h3>Use dev router to see sent emails</h3>
<p>On <code>lib/project_web/router.ex</code>:</p>
<pre><code class="language-elixir">if Mix.env() == :dev do
  forward "/sent_emails", Bamboo.SentEmailViewerPlug
end
</code></pre>
<h2>GenServer</h2>
<h3><em>save code</em></h3>
<pre><code class="language-elixir">defmodule Inmana.Supplies.Scheduler do
  use GenServer

  def init(state \\ %{}) do
    {:ok, state}
  end

  # async
  def handle_cast({:put, key, value}, state) do
    {:noreply, Map.put(state, key, value)}
  end

  # sync
  def handle_call({:get, key}, _from, state) do
    {:reply, Map.get(state, key), state}
  end
end
</code></pre>
<h2>Tests</h2>
<h3>Common tests</h3>
<pre><code class="language-elixir">use ExUnit.Case

describe "function/1" do
  test "description for this test" do
    params = "The params for the function"
    expected_result = "Expected result"

    result = Module.function(params)

    assert result == expected_result
  end
end
</code></pre>
<h3>Changeset tests</h3>
<pre><code class="language-elixir">use Project.DataCase

alias Ecto.Changeset

describe "changeset/1" do
  test "when all params are valid, return a valid changeset" do
    params = %{name: "Siri cascudo", email: "siri@cascudo.com"}

    response = Schema.changeset(params)

    assert %Changeset{
    changes: %{
      name: "Siri cascudo",
      email: "siri@cascudo.com"
    },
      valid?: true
    } = response
  end

  test "when there are invalid params, returns a invalid changeset" do
    params = %{name: "S", email: ""}

    expected_response = %{
      email: ["can't be blank"],
      name: ["should be at least 2 character(s)"]
    }

    response = Schema.changeset(params)

    assert %Changeset{valid?: false} = response
    assert errors_on(response) == expected_response
  end
end
</code></pre>
<h3>Controller tests</h3>
<pre><code class="language-elixir">use ProjectWeb.ConnCase

describe "create/2" do
  test "when all params are valid, create user", %{conn: conn} do
    params = %{name: "Siri cascudo", email: "siri@cascudo.com"}

    response =
      conn
      |> post(Routes.controller_path(conn, :create, params))
      |> json_response(:created)

    assert %{
      "message" => "User Created!",
      "user" => %{
         "email" => "siri@cascudo.com",
        "id" => _id,
        "name" => "Siri cascudo"
      }
    } = response
  end

  test "when there are invalid params, return an error", %{conn: conn} do
    params = %{email: "siri@cascudo.com"}
    expected_response = %{"message" => %{"name" => ["can't be blank"]}}

    response =
      conn
      |> post(Routes.controller_path(conn, :create, params))
      |> json_response(:bad_request)

    assert response == expected_response
  end
end
</code></pre>
<h3>View tests</h3>
<pre><code class="language-elixir">use ProjectWeb.ConnCase

import Phoenix.View

alias ProjectWeb.UserView

describe "render/2" do
  test "renders create.json" do
    params = %{name: "Siri cascudo", email: "siri@cascudo.com"}
    {:ok, restaurant} = Project.create_user(params)

    response = render(UserView, "create.json", user: user)

    assert %{
      message: "User Created!",
      user: %User{
        email: "siri@cascudo.com",
        id: _id,
        name: "Siri cascudo"
      }
    } = response
  end
end

</code></pre>
<hr>
<h1>referencies</h1>
<p>Rocketseat: <a href="https://rocketseat.com.br/"><em>https://rocketseat.com.br/</em></a></p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>nlw5</category>
            <category>rocketseat</category>
            <category>elixir</category>
            <category>server</category>
            <category>tasks</category>
            <category>genserver</category>
            <category>phoenix</category>
            <category>ecto</category>
            <category>tips</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/nlw5-elixir-notes/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Sqlite3 With Python]]></title>
            <link>https://mateusf.com/blog/post/sqlite3-with-python</link>
            <guid>sqlite3-with-python</guid>
            <pubDate>Sat, 20 Mar 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Manage a SQLite3 database with Python]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/sqlite3-with-python/thumbnail" alt=""> ## Connection</p>
<p>First, we need to create a connection with database:</p>
<pre><code class="language-python">import sqlite3
from sqlite3 import Error

def create_connection(db_file):
  '''Create a database connection to a SQLite database'''

  conn = None

  try:
    conn = sqlite3.connect(db_file)
    print(sqlite3.version)
  except Error as e:
    print(e)
  finally:
    if conn:
    conn.close()
</code></pre>
<p>To create a connection, it's needed to invoke the function <code>connect()</code> from <code>sqlite3</code>, and save it in a variable.<br>
In this case the connection was saved in <code>conn</code>, this variable will receive all the queries.</p>
<p>After running this on python3 interactive shell we will receive the version of sqlite library and the database will be generated:</p>
<p><code>$ python3</code></p>
<pre><code>>>> from create_connection import create_connection
>>> create_connection('my_database.db')
2.6.0
>>>
</code></pre>
<p><img src="assets/screenshot_1.png" alt="../assets/sqlite3-with-python/screenshot_1"></p>
<p>If you pass file name as ':memory:', the database will be saved on the memory of computer:</p>
<p><img src="assets/screenshot_2.png" alt="/assets/sqlite3-with-python/screenshot_2"></p>
<h2>Refactor 1</h2>
<p>Before of all, lets create a class where will contain all the methods:</p>
<p><code>db_manager.py</code></p>
<pre><code class="language-python">class DB_Manager:
  def __init__(self):
    self.conn = None

  def create_connection(self, db_file="database.db"):
    try:
      self.conn = sqlite3.connect(db_file)
    except Error as e:
      print(e)
</code></pre>
<h2>Create tables</h2>
<p>let's add the function <code>create_table()</code> to the class:</p>
<pre><code class="language-python">def create_table(self, create_table_sql):
  """ create a table from the create_table_sql statement
  :param conn: Connection object
  :param create_table_sql: a CREATE TABLE statement
  :return:
  """

  try:
    c = self.conn.cursor()
    c.execute(create_table_sql)
  except Error as e:
    print(e)

</code></pre>
<p>With the <code>DB_Manager</code>, let's run the Python Interactive Shell:</p>
<pre><code class="language-bash">$ python3
</code></pre>
<p>Let's import the <code>DB_Manager</code>:</p>
<pre><code class="language-python">>>> from db_manager import DB_manager
</code></pre>
<p>then declare the variable containing the database name:</p>
<pre><code class="language-python">>>> database = 'pythonsqlite.db'
</code></pre>
<p>then, declare the variable containing the SQL statement of project table and the task table:</p>
<pre><code class="language-python">>>> sql_create_projects_table = """ CREATE TABLE IF NOT EXISTS projects (
                                      id integer PRIMARY KEY,
                                      name text NOT NULL,
                                      begin_date text,
                                      end_date text
                                    ); """
>>> sql_create_tasks_table = """ CREATE TABLE IF NOT EXISTS tasks (
                                  id integer PRIMARY KEY,
                                  name text NOT NULL,
                                  priority integer,
                                  status_id integer NOT NULL,
                                  project_id integer NOT NULL,
                                  begin_date text NOT NULL,
                                  end_date text NOT NULL,
                                  FOREIGN KEY (project_id) REFERENCES projects (id)
                                ); """
</code></pre>
<p>then, we will instantiate the <code>DB_Manager</code> and create the connection:</p>
<pre><code class="language-python">>>> db_manager = DB_Manager()
>>> db_manager.create_connection()
</code></pre>
<p>after, let's create the tables:</p>
<pre><code class="language-python">>>> if db_manager.conn is not None:
        # create projects table
        db_manager.create_table(sql_create_projects_table)

        # create tasks table
        db_manager.create_table(sql_create_tasks_table)
    else:
        print("Error! cannot create the database connection.")
</code></pre>
<p>If we run <code>ls</code> we will see that <code>database.db</code> was created:</p>
<p><img src="assets/screenshot_3.png" alt="/assets/sqlite3-with-python/screenshot_3"></p>
<p>Now we can use the command <code>sqlite3</code> passing our database as a param, then, run the <code>.tables</code> command to see the tables that we created:</p>
<p><img src="assets/screenshot_4.png" alt="/assets/sqlite3-with-python/screenshot_4"></p>
<h2>Refactor 2</h2>
<p>First, let's write the connection and the insert statement as a hard code on <code>__init__</code> function:</p>
<pre><code class="language-python"># ...code

  def __init__(self, db_file="database.db"):
    try:
      # create connection
      self.conn = sqlite3.connect(db_file)
    except Error as e:
      print(e)

    # create projects table
    self.create_table(""" CREATE TABLE IF NOT EXISTS projects (
                            id integer PRIMARY KEY,
                            name text NOT NULL,
                            begin_date text,
                            end_date text
                          );
                      """)

    # create tasks table
    self.create_table(""" CREATE TABLE IF NOT EXISTS tasks (
                            id integer PRIMARY KEY,
                            name text NOT NULL,
                            priority integer,
                            status_id integer NOT NULL,
                            project_id integer NOT NULL,
                            begin_date text NOT NULL,
                            end_date text NOT NULL,
                            FOREIGN KEY (project_id) REFERENCES projects (id)
                          );
                      """)


# code...
</code></pre>
<p>Then, delete the <code>create_connection</code> function.</p>
<h2>Insert Data</h2>
<p>To add data to the tables, we need the function <code>execute</code> of the <code>Cursor</code> object. The <code>execute</code> function receive two params, the sql statement and a tuple with the data, after this, we need to run the <code>commit</code> function of the connection, something like this:</p>
<pre><code class="language-python">cur = conn.cursor()
cur.execute(sql, data)
conn.commit()
</code></pre>
<p>Let's create the function to add data on projects table and the tasks tables with this logic:</p>
<pre><code class="language-python"># ...code

def create_project(self, project):
  """ create new project into the project table
  :param conn:
  :param project:
  :return: project id
  """

  sql = ''' INSERT INTO projects(name, begin_date, end_date)
  VALUES(?,?,?) '''

  cur = self.conn.cursor()

  cur.execute(sql, project)
  self.conn.commit()

  return cur.lastrowid

def create_task(self, task):
  """ create new task
  :param conn:
  :param task:
  :return:
  """

  slq = ''' INSERT INTO tasks(name, priority, status_id, project_id, begin_date, end_date)
  VALUES(?,?,?,?,?,?)'''

  cur = self.conn.cursor()

  cur.execute(slq, task)
  self.conn.commit()

  return cur.lastrowid


# code...
</code></pre>
<p>Running the python3 interactive shell, import the class and instantiate it in the <code>db_manager</code> variable:</p>
<pre><code class="language-python">>>> from db_manager import DB_Manager
>>> db_manager = DB_Manager()
</code></pre>
<p>after that, create the variable containing the project data, and a variable to save the project id on database:</p>
<pre><code class="language-python">>>> project = ('Cool App with SQLite &#x26; Python', '2021-03-20', '2021-03-23')
>>> project_id = db_manager.create_project(project)
</code></pre>
<p>then, create two tasks and save it on the database:</p>
<pre><code class="language-python">>>> task_1 = ('Analyze the requirements of the app', 1, 1, project_id, '2021-03-20', '2021-03-23')
>>> task_2 = ('Confirm with user about the top requirements', 1, 1, project_id, '2021-03-20', '2021-03-23')
>>> db_manager.create_task(task_1)
1
>>> db_manager.create_task(task_2)
2
</code></pre>
<p>The project and the tasks are saved now. Open the database to see the data.</p>
<p>With the open database, use this commands to format the output:</p>
<pre><code class="language-bash">sqlite> .header on
sqlite> .mode column
</code></pre>
<p>Use the <code>SELECT</code> statement to get data from <code>projects</code> table:</p>
<pre><code class="language-sql">SELECT * FROM projects;
</code></pre>
<p><img src="assets/screenshot_5.png" alt="/assets/sqlite3-with-python/screenshot_5"></p>
<p>Use the same statement to get data from <code>tasks</code> table:</p>
<pre><code class="language-sql">SELECT * FROM tasks;
</code></pre>
<p><img src="assets/screenshot_6.png" alt="/assets/sqlite3-with-python/screenshot_6"></p>
<hr>
<h2>referencies:</h2>
<p>SQLite Python: <a href="https://www.sqlitetutorial.net/sqlite-python/">https://www.sqlitetutorial.net/sqlite-python/</a> [<a href="https://web.archive.org/web/20210922122212/https://www.sqlitetutorial.net/sqlite-python/"><em>archive</em></a>]</p>
<ul>
<li>Creating a New Database: <a href="https://www.sqlitetutorial.net/sqlite-python/creating-database/">https://www.sqlitetutorial.net/sqlite-python/creating-database/</a> [<a href="https://web.archive.org/web/20210922122523/https://www.sqlitetutorial.net/sqlite-python/creating-database/"><em>archive</em></a>]</li>
<li>Creating Tables: <a href="https://www.sqlitetutorial.net/sqlite-python/create-tables/">https://www.sqlitetutorial.net/sqlite-python/create-tables/</a> [<a href="https://web.archive.org/web/20210922122450/https://www.sqlitetutorial.net/sqlite-python/create-tables/"><em>archive</em></a>]</li>
<li>Insert data: <a href="https://www.sqlitetutorial.net/sqlite-python/insert/">https://www.sqlitetutorial.net/sqlite-python/insert/</a> [<a href="https://web.archive.org/web/20210922122231/https://www.sqlitetutorial.net/sqlite-python/insert/"><em>archive</em></a>]</li>
</ul>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>database</category>
            <category>sqlite</category>
            <category>crud</category>
            <category>python</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/sqlite3-with-python/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Learn Elixir #4]]></title>
            <link>https://mateusf.com/blog/post/learn-elixir-4</link>
            <guid>learn-elixir-4</guid>
            <pubDate>Thu, 18 Feb 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[binaries, strings, and charlists]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/learn-elixir-4/thumbnail" alt=""> ## Unicode and Code Points</p>
<p><strong>You can use <code>?</code> before a character literal to see your code point</strong></p>
<pre><code class="language-elixir">iex> ?a
97
iex> ?ł
322
</code></pre>
<pre><code class="language-elixir">iex> "\u0061" === "a"
true
iex>0x0061 = 97 = ?a
97
</code></pre>
<h2>UTF-8 and Encodings</h2>
<p><strong>Elixir uses UTF-8 to encode its strings, which means that code are encoded as a series of 8-bit bytes</strong></p>
<p><strong><code>String.length/1</code> count graphemes, but <code>byte_size/1</code> reveals the number of underlying raw bytes needed to store the string when using UTF-8. UTF-8 requires one byte to represent the characters <code>h</code>, <code>e</code>, and <code>o</code>, but two bytes to represent <code>ł</code></strong></p>
<pre><code class="language-elixir">iex> string = "hełło"
iex> String.length(string)
5
iex> byte_size(string)
7
</code></pre>
<h2>Charlist</h2>
<p><strong>A charlist is a list of integers where all the integers are valid code points</strong></p>
<pre><code class="language-elixir">iex> 'hełło'
[104, 101, 322, 322, 111]
iex> is_list 'hełło'
true
iex> 'hello'
'hello'
iex> List.first('hello')
104
</code></pre>
<pre><code class="language-elixir">iex> heartbeats_per_minute = [99, 97, 116]
'cat'
</code></pre>
<pre><code class="language-elixir">iex> to_charlist "hełło"
[104, 101, 322, 322, 111]
iex> to_string 'hełło'
"hełło"
iex> to_string :hello
"hello"
iex> to_string 1
"1"
</code></pre>
<pre><code class="language-elixir">iex> 'this ' &#x3C;> 'fails'
** (ArgumentError) expected binary argument in &#x3C;> operator but got: 'this '
    (elixir) lib/kernel.ex:1821: Kernel.wrap_concatenation/3
    (elixir) lib/kernel.ex:1808: Kernel.extract_concatenations/2
    (elixir) expanding macro: Kernel.&#x3C;>/2
    iex:1: (file)
iex> 'this ' ++ 'works'
'this works'
iex> "he" ++ "llo"
** (ArgumentError) argument error
    :erlang.++("he", "llo")
iex> "he" &#x3C;> "llo"
"hello"
</code></pre>
<hr>
<h2>referencies</h2>
<p>Binaries, strings, and charlists: <a href="https://elixir-lang.org/getting-started/binaries-strings-and-char-lists.html">https://elixir-lang.org/getting-started/binaries-strings-and-char-lists.html</a> [<a href="https://web.archive.org/web/20210920215640/https://elixir-lang.org/getting-started/binaries-strings-and-char-lists.html"><em>archive</em></a>]</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>getting-start</category>
            <category>cli</category>
            <category>code</category>
            <category>programming</category>
            <category>elixir</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/learn-elixir-4/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Learn Elixir #3]]></title>
            <link>https://mateusf.com/blog/post/learn-elixir-3</link>
            <guid>learn-elixir-3</guid>
            <pubDate>Wed, 17 Feb 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[cond and if/unless statements and do/end blocks]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/learn-elixir-3/thumbnail" alt=""> ## Cond</p>
<p><strong>Useful to make multi conditions with different values and return the first that match true</strong></p>
<pre><code class="language-elixir">cond do
  2 + 2 == 5 ->
    "This will not be true"
  2 * 2 == 3 ->
    "Nor this"
  1 + 1 == 2 ->
    "But this will"
end
</code></pre>
<pre><code class="language-elixir">"But this will"
</code></pre>
<p><strong>This is equivalent to <code>else if</code> clause in many imperative languages (used much less here)</strong></p>
<p><strong>Is necessary add a final condition equal <code>true</code>, which always will match, because if all the conditions return <code>nil</code> of <code>false</code>an error <code>CondClauseError</code> is raised</strong></p>
<pre><code class="language-elixir">cond do
  2 + 2 == 5 ->
    "This is never true"
  2 * 2 -> 3
    "Nor this"
  true ->
    "This is always true, equivalent to else"
end
</code></pre>
<pre><code class="language-elixir">"This is always true, equivalent to else"
</code></pre>
<p><strong><code>cond</code> considers any value besides <code>nil</code> or <code>false</code> to be <code>true</code></strong></p>
<pre><code class="language-elixir">cond do
  hd([1, 2, 3]) -> "1 is considered as true"
end
</code></pre>
<pre><code class="language-elixir">"1 is considered true"
</code></pre>
<h2>If/Unless</h2>
<p><strong>Elixir provide macros <code>if/2</code> and <code>unless/2</code> which are useful when you need to check for only on condition</strong></p>
<p><em><code>if</code></em></p>
<pre><code class="language-elixir">if true do
  "This works!"
end
</code></pre>
<pre><code class="language-elixir">"This works!"
</code></pre>
<p><em><code>unless</code></em></p>
<pre><code class="language-elixir">unless true do
  "This is will never be seen"
end
</code></pre>
<pre><code class="language-elixir">nil
</code></pre>
<p><strong>They also support <code>else</code></strong></p>
<pre><code class="language-elixir">if nil do
  "This won't be seen"
else
  "This will"
end
</code></pre>
<pre><code class="language-elixir">"This will"
</code></pre>
<h2><code>do/end</code> blocks</h2>
<pre><code class="language-elixir">iex> if true, do: 1 + 2
2
iex> if false, do: :this, else: :that
:that
</code></pre>
<p>These are equivalent:</p>
<p><em>code/1</em></p>
<pre><code class="language-elixir">if true do
  a = 1 + 2
  a + 10
end
</code></pre>
<p><em>code/2</em></p>
<pre><code class="language-elixir">if true, do: (
  a = 1 + 2
  a + 10
)
</code></pre>
<p><em>out/all</em></p>
<pre><code>13
</code></pre>
<hr>
<h2>referencies</h2>
<p>Elixir Conditions: <a href="https://elixir-lang.org/getting-started/case-cond-and-if.html">https://elixir-lang.org/getting-started/case-cond-and-if.html</a> [<a href="https://web.archive.org/web/20210920215626/https://elixir-lang.org/getting-started/case-cond-and-if.html"><em>archive</em></a>]</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>getting-start</category>
            <category>cli</category>
            <category>code</category>
            <category>programming</category>
            <category>elixir</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/learn-elixir-3/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Learn Elixir #2]]></title>
            <link>https://mateusf.com/blog/post/learn-elixir-2</link>
            <guid>learn-elixir-2</guid>
            <pubDate>Tue, 16 Feb 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Case Condition and Anonymous Functions guards]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/learn-elixir-2/thumbnail" alt=""> ## Case</p>
<pre><code class="language-elixir">case {1, 2, 3} do
  {1, _x, 3} ->
    "This clause will match and bind _x to 2 in this clause"

  {4, 5, 6} ->
    "This clause won't match"

   _ ->
    "This clause would match any value"
end
</code></pre>
<pre><code class="language-elixir">"This clause will match and bind _x to 2 in this clause"
</code></pre>
<p><strong>To use pattern match you need to use pin<code>^</code> operator</strong></p>
<pre><code class="language-elixir">x = 1

case 10 do
  ^x -> "Won't match"
  _ -> "Will match"
end
</code></pre>
<pre><code class="language-elixir">"Will match"
</code></pre>
<p><strong>Clause allow extra conditions to be specified via guards</strong></p>
<pre><code class="language-elixir">case {1, 2, 3} do
  {1, x, 3} when x > 0 ->
    "Will match"
  _ ->
    "Would match, if guard condition were not satisfied"
end
</code></pre>
<pre><code class="language-elixir">"Will match"
</code></pre>
<p><strong>Erros in guards will not leak but simply make the guard fail</strong></p>
<pre><code class="language-elixir">iex> hd(1)
** (ArgumentError) argument error
  :erlang.hd(1)
</code></pre>
<pre><code class="language-elixir">case 1 do
  x when hd(x) -> "Won't match"
  x -> "Got #{x}"
end
</code></pre>
<pre><code class="language-elixir">"Got 1"
</code></pre>
<p><strong>Anonymous Functions can also have multiple clauses and guards</strong></p>
<pre><code class="language-elixir">f = fn
  x, y when x > 0 -> x + y
  x, y -> x * y
end
</code></pre>
<pre><code class="language-elixir">iex> f.(1, 3)
4
iex> f.(-1, 3)
-3
</code></pre>
<hr>
<h2>referencies</h2>
<p>Elixir Conditions: <a href="https://elixir-lang.org/getting-started/case-cond-and-if.html">https://elixir-lang.org/getting-started/case-cond-and-if.html</a> [<a href="https://web.archive.org/web/20210920215626/https://elixir-lang.org/getting-started/case-cond-and-if.html"><em>archive</em></a>]</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>getting-start</category>
            <category>cli</category>
            <category>code</category>
            <category>programming</category>
            <category>elixir</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/learn-elixir-2/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Learn Elixir]]></title>
            <link>https://mateusf.com/blog/post/learn-elixir</link>
            <guid>learn-elixir</guid>
            <pubDate>Tue, 02 Feb 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Running scripts and study Basic types]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/learn-elixir/thumbnail" alt=""> ## <a href="https://elixir-lang.org/getting-started/introduction.html">Introduction</a></p>
<p><em>Interactive mode</em>: <strong>iex</strong></p>
<p><em>Initial Commands</em>:</p>
<pre><code class="language-elixir">iex> 40 + 2
42
iex> "hello" &#x3C;> " world"
"hello world"
</code></pre>
<p><em>Running Scripts</em>: <code>elixir hello-word.exs</code></p>
<p><em>Hello Word:</em></p>
<pre><code class="language-elixir">IO.puts "Hello Word"
</code></pre>
<pre><code class="language-elixir">"Hello Word"
</code></pre>
<h2><a href="https://elixir-lang.org/getting-started/basic-types.html">Basic types</a></h2>
<h3><em>Get Data Type</em>: <code>i data</code></h3>
<pre><code class="language-elixir">iex> i 1
</code></pre>
<p>will show something like this:</p>
<pre><code>Term
  1
Data type
  Integer
Reference modules
  Integer
Implemented protocols
  IEx.Info, Inspect, List.Chars, String.Chars
</code></pre>
<h3><em>Basic Types</em></h3>
<pre><code class="language-elixir">iex> 1          # integer
iex> 0x1F       # integer
iex> 1.0        # float
iex> true       # boolean
iex> :atom      # atom / symbol
iex> "elixir"   # string
iex> [1, 2, 3]  # list
iex> {1, 2, 3}  # tuple
</code></pre>
<h3><em>Math</em></h3>
<pre><code class="language-elixir">iex> 1 + 2
3
iex> 5 * 5
25
iex> 10 / 2
5.0
</code></pre>
<p><code>10/2</code> always return a float number, to get an integer, use <code>div</code> and <code>rem</code> functions:</p>
<pre><code class="language-elixir">iex> div(10, 2)
5
iex> div 10, 2
5
iex> rem 10, 3
1
</code></pre>
<h3><em>Shortcut Notations</em></h3>
<pre><code class="language-elixir">iex> 0b1010 # binary
10
iex> 0o777 # octal
511
iex> 0x1F # hexadecimal
31
</code></pre>
<h3><em>Scientific Notation</em></h3>
<pre><code class="language-elixir">iex> 1.0
1.0
iex> 1.0e-10
1.0e-10
</code></pre>
<h3><em>Round Function</em></h3>
<pre><code class="language-elixir">iex> round(3.58)
4
iex> trunc(3.58)
3
</code></pre>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>getting-start</category>
            <category>cli</category>
            <category>code</category>
            <category>programming</category>
            <category>elixir</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/learn-elixir/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Neovim]]></title>
            <link>https://mateusf.com/blog/post/neovim</link>
            <guid>neovim</guid>
            <pubDate>Wed, 16 Dec 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[How to install, use and configure Neovim]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/neovim/thumbnail" alt=""> ## O que é?</p>
<p><a href="https://neovim.io/">Neovim</a> é um editor de texto baseado no Vim que roda via CLI (Linha de comando), com a possibilidade de instala plugins.</p>
<h2>Instalar neovim</h2>
<p>Executei o comando</p>
<pre><code class="language-bash">$ sudo apt install python3-neovim
</code></pre>
<p>no Parrot Sec 4.10 e ele instalou o neovim e os módulos python para ele automaticamente.</p>
<p>A forma mais direta de instalar usando uma distribuição debian-based é com</p>
<pre><code class="language-bash">$ sudo apt install neovim
</code></pre>
<p>Para abrir o neovim basta executar o comando <code>nvim</code> no terminal.</p>
<p>Arquivo de configurações do neovim:<br>
<code>~/.config/nvim/init.vim</code></p>
<h2>Uso</h2>
<p>O padrão do neovim é baseado no vim, então todos os comandos do vim funcionam no neovim.</p>
<p>O vim possui 2 modos, modo de edição e modo de comando, o modo de edição é o modo onde podemos editar o arquivo, pode ser ativado com a tecla <code>INSERT</code>, e o modo de comando é o modo onde podemos rodar comandos do vim, para ativar o modo comando pressione a tecla <code>ESC</code>.</p>
<p>Todos os comandos do neovim devem ser adicionados após <code>:</code> no buffer do neovim.</p>
<h3>Comandos</h3>
<table>
<thead>
<tr>
<th>descrição</th>
<th>comando</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sair</td>
<td><code>:q</code></td>
</tr>
<tr>
<td>Sair sem salvar</td>
<td><code>:q!</code></td>
</tr>
<tr>
<td>Salvar um arquivo</td>
<td><code>:w</code></td>
</tr>
<tr>
<td>Salvar e sair</td>
<td><code>:wq</code></td>
</tr>
<tr>
<td>Deletar um character</td>
<td><code>x</code></td>
</tr>
<tr>
<td>Desfazer uma ação</td>
<td><code>u</code></td>
</tr>
<tr>
<td>Procurar uma letra ou palavra</td>
<td><code>/palavra</code></td>
</tr>
</tbody>
</table>
<h3>Atalhos</h3>
<p>Alguns atalhos do modo de edição</p>
<p>Ir para o início da linha - <code>home</code></p>
<p>Ir para o final da linha - <code>end</code></p>
<p>Navegar para cima e para baixo - <code>Page Up</code> e <code>Page Down</code></p>
<p>Apagar uma linha - <code>CTRL+U</code></p>
<h2>Instalar Plugins</h2>
<h3>step-by-step</h3>
<p>O gerenciador de plugins que vou usar é o <a href="https://github.com/junegunn/vim-plug">VimPlug</a>.</p>
<h4>Configurar nvim para instalar pluggins:</h4>
<p>Instale o gerenciador VimPlug:</p>
<pre><code class="language-bash">curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
</code></pre>
<p>Adicione essas linhas no <code>~/.config/nvim/init.vim</code></p>
<pre><code class="language-vim">call plug#begin()
" Your plugins...
call plug#end()
</code></pre>
<p><em>ex:</em></p>
<pre><code class="language-vim">call plug#begin()
Plug 'roxma/nvim-completion-manager'
Plug 'SirVer/ultisnips'
Plug 'honza/vim-snippets'
call plug#end()
</code></pre>
<h4>Instalar plugins</h4>
<p>Você pode encontrar muitos plugins no site <a href="https://vimawesome.com/">VimAwesome</a>. Escolha um e adicione as linhas do plugins entre a função <code>call plug#begin()</code> e <code>call plug#end()</code> no arquivo <code>~/.config/nvim/init.vim</code>.</p>
<pre><code class="language-vim">call plug#begin()
Plug 'valloric/youcompleteme'
call plug#end()
</code></pre>
<p>segundo o padrão <code>Plug 'nomedodesenvolvedor/nomedoplugin'</code>.</p>
<p>depois execute os comandos a seguir no nvim</p>
<pre><code>:PlugInstall
:UpdateRemotePlugins
</code></pre>
<h3>Meus Plugins</h3>
<h4><strong>emmet-vim</strong></h4>
<p><em>Download</em>: <a href="https://vimawesome.com/plugin/emmet-vim">https://vimawesome.com/plugin/emmet-vim</a></p>
<p><em>Plugin Label</em>: <code>'mattn/emmet-vim'</code></p>
<p><em>Usage</em>:</p>
<p>Escreva a abreviação do código, depois aperte <code>CTRL+Y+,</code>.</p>
<p>ex1:</p>
<pre><code class="language-html">html:5
</code></pre>
<blockquote>
<p><code>CTRL+Y+,</code></p>
</blockquote>
<pre><code class="language-html">&#x3C;!DOCTYPE html>
&#x3C;html lang="en">
  &#x3C;head>
    &#x3C;meta charset="UTF-8" />
    &#x3C;title>&#x3C;/title>
  &#x3C;/head>
  &#x3C;body>&#x3C;/body>
&#x3C;/html>
</code></pre>
<p>ex2:</p>
<pre><code class="language-html">div>ul>li*5
</code></pre>
<blockquote>
<p><code>CTRL+Y+,</code></p>
</blockquote>
<pre><code class="language-html">&#x3C;div>
  &#x3C;ul>
    &#x3C;li>&#x3C;/li>
    &#x3C;li>&#x3C;/li>
    &#x3C;li>&#x3C;/li>
    &#x3C;li>&#x3C;/li>
    &#x3C;li>&#x3C;/li>
  &#x3C;/ul>
&#x3C;/div>
</code></pre>
<p><em>Additional Config</em></p>
<pre><code class="language-vim">let g:user_emmet_leader_key='&#x3C;C-Z>' " remap keybind to CTRL+Z+,
</code></pre>
<h4><strong>jedi-vim</strong></h4>
<p><em>Download</em>: <a href="https://vimawesome.com/plugin/jedi-vim">https://vimawesome.com/plugin/jedi-vim</a></p>
<p><em>Plugin Label</em>: 'davidhalter/jedi-vim'</p>
<p><em>Usage</em>:<br>
Autocomplete de padrões de código</p>
<h4><strong>AutoClose</strong></h4>
<p><em>Download</em>: <a href="https://vimawesome.com/plugin/autoclose">https://vimawesome.com/plugin/autoclose</a></p>
<p><em>Plugin Label</em>: 'townk/vim-autoclose'</p>
<p><em>Usage</em>:<br>
Fecha alguns caracteres de escopo automaticamente, como (), [], {}, '', ""...</p>
<h4><strong>vim-closetag</strong></h4>
<p><em>Download</em>: <a href="https://vimawesome.com/plugin/vim-closetag">https://vimawesome.com/plugin/vim-closetag</a></p>
<p><em>Plugin Label</em>: 'alvan/vim-closetag'</p>
<p><em>Usage</em>: Auto completa tags HTML</p>
<h4><strong>tabnine-vim</strong></h4>
<p><em>Download</em>: <a href="https://www.tabnine.com/install">https://www.tabnine.com/install</a></p>
<p><em>Plugin Label</em>: 'zxqfl/tabnine-vim'</p>
<p><em>Usage</em>: IA para prever textos e oferecer um autocomplete inteligente</p>
<h4><strong>vim-workspace</strong></h4>
<p><em>Download</em>: <a href="https://vimawesome.com/plugin/vim-workspace">https://vimawesome.com/plugin/vim-workspace</a></p>
<p><em>Plugin Label</em>: 'thaerkh/vim-workspace'</p>
<p><em>Usage</em>: Disponibiliza funcionalidades interessantes, mas eu uso so o autosave, porque é o único que sei usar</p>
<p><em>Additional Config</em>:</p>
<pre><code class="language-vim">let g:workspace_autosave_always = 1
</code></pre>
<h4><strong>vim-airline</strong></h4>
<p><em>Download</em>: <a href="https://vimawesome.com/plugin/vim-airline-superman">https://vimawesome.com/plugin/vim-airline-superman</a></p>
<p><em>Plugin Label</em>: 'vim-airline/vim-airline'</p>
<p><em>Usage</em>: Exibe uma barra de status com informações sobre a branch atual, tipo de arquivo, modo de edição, êtc... brabo demais.</p>
<h4><strong>vim-wakatime</strong></h4>
<p><em>Download</em>: <a href="https://wakatime.com/vim">https://wakatime.com/vim</a></p>
<p><em>Plugin Label</em>: 'wakatime/vim-wakatime'</p>
<p><em>Usage</em>: Disponibiliza uma dashboard com estatísticas de tempo em uma determinada linguagem, projeto, editor...<br>
Tudo isso no site da Wakatime</p>
<h4><strong>editorconfig-vim</strong></h4>
<p><em>Download</em>: <a href="https://github.com/editorconfig/editorconfig-vim">https://github.com/editorconfig/editorconfig-vim</a></p>
<p><em>Plugin Label</em>: 'editorconfig/editorconfig-vim'</p>
<p><em>Usage</em>: Padroniza configuração de editores através do arquivo <code>.editorconfig</code></p>
<hr>
<p>referencias:</p>
<p>Installing Neovim: <a href="https://github.com/neovim/neovim/wiki/Installing-Neovim">https://github.com/neovim/neovim/wiki/Installing-Neovim</a> [<a href="https://web.archive.org/web/20210918162758/https://github.com/neovim/neovim/wiki/Installing-Neovim"><em>archive</em></a>]</p>
<p>How to find a Word in Vim or vi text editor: <a href="https://www.cyberciti.biz/faq/find-a-word-in-vim-or-vi-text-editor/">https://www.cyberciti.biz/faq/find-a-word-in-vim-or-vi-text-editor/</a> [<a href="https://web.archive.org/web/20210918162917/https://www.cyberciti.biz/faq/find-a-word-in-vim-or-vi-text-editor/"><em>archive</em></a>]</p>
<p>How to Install NeoVim and Plugins with vim-plug: <a href="https://www.linode.com/docs/guides/how-to-install-neovim-and-plugins-with-vim-plug/">https://www.linode.com/docs/guides/how-to-install-neovim-and-plugins-with-vim-plug/</a> [<a href="https://web.archive.org/web/20210918163307/https://www.linode.com/docs/guides/how-to-install-neovim-and-plugins-with-vim-plug/"><em>archive</em></a>]</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>cli</category>
            <category>step-by-step</category>
            <category>plugins</category>
            <category>editor</category>
            <category>programming</category>
            <category>code</category>
            <category>vim</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/neovim/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Learn With Ethereum #2]]></title>
            <link>https://mateusf.com/blog/post/learn-with-ethereum-2</link>
            <guid>learn-with-ethereum-2</guid>
            <pubDate>Sat, 12 Dec 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[Criptografando mensagens com chave pública]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/learn-with-ethereum-2/thumbnail" alt=""> {/* VARIABLED BLOCK */}</p>
<p>{/* VARIABLED BLOCK */}</p>
<h2>Encryption (side quest)</h2>
<p><img src="assets/screenshot_10.png" alt="/assets/learn-with-ethereum/screenshot_10.png"><br>
<a href="https://sandbox.eth.build/wofCrGxhc3Rfbm9kZV9pZMONAXHEgcSDxIVsaW5rxIvEjQFQwqXEh8SJc8KWworCosSMxI5pwqR0eXBlwqpJbnB1dC9UZXh0wqNwb3PCkijDjMKWwqRzaXplwpLEjiwywqVmxIJnc8KBwqljb2zEgnBzZWTDg8Klb3LEiXIAwqRtxIhlAMKmxJXErnRzwpHCg8KkbmFtZcKgxKbEqMWgwqTElMSWw4DCp2_Er8WkxabFqMWqxazFrsSnxKnCpsSEcsSVZ8KlxbNrxabEjknCqnByb8SpcnRpZXPChMKrYmxvY2vGk1PFgGUywqtwxIJjZWjFj8Wawq9lbnRlciDGrcS0IGjGrmXCpcaSdGxlwqTEssS0wqV2YWx1xrbHgWnGpcShxKMBaMWvxKnCq0NyxKh0by9IxINoxLbEuMS6w4zDksS-xp_CkngexYfFicWLxY3Fj8WRxZPFlcWXxZnGrgHFncWfxaHFo8SvxbrFqcWrxrbHsXTHjGXCrcaCxoQsbnVtYsauxbLElWvGisW2xbjHssWnx7TFrMKkaMeWx7nGgXTGg27GhcaHxokBS8aMxo7GkMaSxpTCgMeIxJlrx7nCr8ePx5HHk0tleSBQYWlyx5jEucOMw4jDjMK0x53FgcKCwqEww4pDU8KZwprCoTFCx6JhxYrCgMeqxZoCx67EicewxK3HssKSxbvHtcKtW8aNaceAxq0ga8iqXciRx7zIlciExJbEjkvJkcWswqhnxqvGrmHGrce5w7_JoGvFtcW3dMW5wpPJpGXGosaDyZdlyZnIqsmdyJPGhMaGyIVzw4DJtcaMdcaYx4bJu3nJvciUyJbKgcKRxI5OybXCp2FkZHLGlHPKi8m_yJfKjwFMyJvGj8auyJ5zyKDEosSZb8e5x47HkHDHkseUx5bIscWDAcK4w4zDpsi3xYLHoMmExYrFjMWOxZBhxZLFlMWWxZjFmgPJi8WgxaLJjsWlyIvFvMe2y4jHuce7yb7Ilce-yIDIgnLJrsqQyIjJssiKybXIjsiQxb9lyJLKjMqAxJbImE_KoMidxpPKpMihxI5wy45EaXPGo2F5L1fJqmPHl8S3xLnEjsOCxYTKtsWDAzE8yrnKpMmIxq4Fy4XJjcW5wpHChMiMxa3HucWcxofEjk_GhmHIgmzCoMuYzIrMjMuLxb7FsADLosaIw4DMlMyWwqDLpsqiy6jCgca3aca5xrbLtXTLt8KJyqbEjmzIpMuuy7DEgsuzQcqVypdzc8qwy7vEjsKay77EjlTEm8WIyYXMhMuCxq4EzIjLh8yKybXMncSpzJDIhcSOyp_GjcqhxpHLqMKDxpfGmcabxp3Gn8ahy7HGpcanbMWawqDMqsyswqfMusqWypjMoHPClcKWxorEpADEjmgAy4_KjMuSyIHGrs2xyJnNtc20AWvFocmeZ829TMSOawLMswAAzb1OzogBxI5vzbfOhM26y5TNvU_Oks6AcM6MwqZnxo51xZLCkMKmxY5uZmlnwoDCp3bGrsS_b27Diz_DmcKZzrTOtMKa"><em>click here to edit this workflow on eth.build</em></a></p>
<p>disclaimer: Todos esses blocos ja são conhecidos portando não vou reexplica-los, se quiser revisar veja o <a href="/post/learn-with-ethereum">primeiro post</a> da série.</p>
<p>O legal desse workflow é pra notar algo, o endereço gerado pelo <strong>KEY PAIR</strong>. Se você notar, o <em>address</em> são os 42 últimos caracteres da <em>hash</em> da <em>public key</em>.</p>
<h3>Encrypt a message</h3>
<p><img src="assets/screenshot_11.png" alt="/assets/learn-with-ethereum/screenshot_11.png"><br>
<a href="https://sandbox.eth.build/wofCrGxhc3Rfbm9kZV9pZMONAXrEgcSDxIVsaW5rxIvEjQFYwqXEh8SJc8KWworCosSMxI5pwqR0eXBlwqpJbnB1dC9UZXh0wqNwb3PCknLDjMKewqRzaXplwpLEjiwywqVmxIJnc8KBwqljb2zEgnBzZWTDg8Klb3LEiXIAwqRtxIhlAMKmxJXErnRzwpHCg8KkbmFtZcKgxKbEqMWgwqTElMSWw4DCp2_Er8WkxabFqMWqxazFrsSnxKnCpsSEcsSVZ8KlxbNrxabEjknCqnByb8SpcnRpZXPChMKrYmxvY2vGk1PFgGUywqtwxIJjZWjFj8Wawq9lbnRlciDGrcS0IGjGrmXCpcaSdGxlwqTEssS0wqV2YWx1xrbHgWnGpcShxKMBaMWvxKnCq0NyxKh0by9IxINoxLbEuMS6w4zDmsS-xp_CkngexYfFicWLxY3Fj8WRxZPFlcWXxZnGrgLFncWfxaHFo8SvxbrFqcWrxrbHsXTHjGXCrcaCxoQsbnVtYsauxbLElWvGisW2xbjHssWnx7TFrMKkaMeWx7nGgXTGg27GhcaHxokBS8aMxo7GkMaSxpTCgMeIxJlrx7nCr8ePx5HHk0tleSBQYWlyx5jEucSOGMOMwrrHncWBwoLCoTDDikNTwpnCmsKhMULHomHFisKAx6rFmgPHrsSJx7DErceywpLFu8e1wq1bxo1px4DGrSBryKpdyJHHvMiVyITElsSOS8mRxazCqGfGq8auYcatx7nDv8mga8W1xbd0xbnCk8mkZcaixoPJl2XJmciqyZ3Ik8aExobIhXPDgMm1xox1xpjHhsm7ecm9yJTIlsqBwpHEjljJtcKnYWRkcsaUc8qLyb_Il8KQyJvGj8auyJ5zyKDEosSZeMe5wq7IpnDHki9FbmPHkMqqyLHFgwImxI4EyLfFgsOMwrQtyYTJhsmIxq7Kt8WeyYzFosmOxaXJkMiMxKrErsqHY8qJyprJn8aHypDKksWsc3PJhca7xb9lyJLKjMmuxI5WyIjJssmPybXCpm9iamVjx7jLmMujy6XLp3TKgMSWyoLJtcKpxqvKr8eRxZTLjsqNy7DKjwFXyp7IncaTyqLIocSOyorLmMSry4XEscSzxLXEt8S5w4zDksSOQMq4xYMBxYXKvcqiyr9yAcmLxaDLhMW5yIvFvMWtx7nFnMaHybDIicWlzJ7HtcW-xbDLmsqbyo7Lncu-yqDMgMaWxpjGmsacZcaexYHGocajYcalxqdsxqnGq8atxq_GsXTGs8a1xrdpxrnGu8a9y67HgMeCZcOZIsa0xZBvIHfFmGTGsGhpcyDNmyDHhcalIGbFmM2fxJTHh8qkxI56x7nCsETNm8y6ecyIxLRBypdhyrLDjQMMxI4OzJHEjsK4w4zClcyVxYzFjsWQYcWSxZTDgsyXBcyayY3Mncm1zKnGgMmeZ8ucy7zLn86Ny4jOj8uZzpHLr8aIw4DMr8aRzIDCgc2HzYnCqM2LzbNlYc6bc8KVwpbGisSkAMSOaADHu8m-yJXHvsiAyIJyzqzImc6wzq8Ba8WhzpHOulbMg869eAHMq8iVzrpXxI7Phs2pz4DOtGfOuljEjmsBz4zPj8qMwqZnxo51xZLCkMKmxY5uZmlnwoDCp3bGrsS_b27Diz_DmcKZz7DPsMKa"><em>click here to edit this workflow on eth.build</em></a></p>
<p>O bloco <strong>ENCRYPT</strong> é o bloco que consegue criptografar uma mensagem usando uma <em>public key</em>, ele recebe como parâmetro a <em>public key</em> e a <em>message</em>. Semelhante ao funcionamento da criptografia <a href="/posts/pgp">PGP</a>.</p>
<p>Parâmetros usados:</p>
<p>Public Key: <code>0x5eed5fa3a67696c334762bb4823e585e2ee579aba3558d9955296d6c04541b426078dbd48d74af1fd0c72aa1a05147cf17be6b60bdbed6ba19b08ec28445b0ca</code></p>
<p>Message: <code>hello word this is alice for alice</code></p>
<p>E devolve a mensagem criptografada: <code>0xabc62f77ba4447a16825e10764687a9902f5bc3c03dab4660dacc1ced1a311665b713113d0ad029e7f174d0c3439b11ebafaacaebbddc897c17f67c8ee3a3d4e8fe861cef74897931e7a09e253fb553a0e0032e55ce503e405b6089505e1529456e684b98150c7a48e7115897c4ceb572e174ead1f60b75a153ed832a5abdda3bc</code></p>
<h3>Decrypt a message</h3>
<p><img src="assets/screenshot_12.png" alt="/assets/learn-with-ethereum/screenshot_12.png"><br>
<a href="https://sandbox.eth.build/wofCrGxhc3Rfbm9kZV9pZMONAcKKxIHEg8SFbGlua8SLxI0BZsKlxIfEiXPClsKKwqLEjMSOacKkdHlwZcKqSW5wdXQvVGV4dMKjcG9zwpJCw4zCvMKkc2l6ZcKSxI4sMsKlZsSCZ3PCgcKpY29sxIJwc2Vkw4PCpW9yxIlyAMKkbcSIZQDCpsSVxK50c8KRwoPCpG5hbWXCoMSmxKjFoMKkxJTElsOAwqdvxK_FpMWmxajFqsWsxa7Ep8SpwqbEhHLElWfCpcWza8WmxI5Jwqpwcm_EqXJ0aWVzwoTCq2Jsb2NrxpNTxYBlMsKrcMSCY2VoxY_FmsKvZW50ZXIgxq3EtCBoxq5lwqXGknRsZcKkxLLEtMKldmFsdca2x4FpxqXEocSjAWjFr8SpwqtDcsSodG8vSMSDaMS2xLjEusOMw7jEvsafwpJ4HsWHxYnFi8WNxY_FkcWTxZXFl8WZxq4CxZ3Fn8WhxaPEr8W6xanFq8a2x7F0x4xlwq3GgsaELG51bWLGrsWyxJVrxorFtsW4x7LFp8e0xazCpGjHlse5xoF0xoNuxoXGh8aJAUvGjMaOxpDGksaUwoDHiMSZa8e5wq_Hj8eRx5NLZXkgUGFpcseYxLnDjMOow4zDmMedxYHCgsKhMMOKQ1PCmcKawqExQseiYcWKwoDHqsWaA8euxInHsMStx7LCksW7x7XCrVvGjWnHgMatIGvIql3Ikce8yJXIhMSWxI5LyZHFrMKoZ8arxq5hxq3HucO_yaBrxbXFt3TFucKTyaRlxqLGg8mXZcmZyKrJnciTxoTGhsiFyJhkybXGjHXGmMeGybt5yb3IlMiWyoHCkMm1wqdhZGRyxpRzyovJv8iXwpDIm8aPxq7InnPIoMSixJnCice5wq7IpnDHki9EZWPHkMqoyLHFgwIoxI4OyLfFgsOMwrQtyYTJhsmIxq4EyYvFoMWiyY7FpcmQyIzJtsmVybnKicqYyZ_Gh8SOyoPLhsKpxqvKrceRxZTLi2fJrsSOZciIybLIism1wqnEicuTyqjLlcW_ZcKmb2Jqyqx0yoDElsiYZsqcyJ3Gk8qgyKHEjnrHucKwRGlzxqNhecSxxLN0QcqVYcqwXMSOXsq2xYMBwrjDjMKVyrvHpMWOxZBhxZLFlMOCyr1yAcuAyY3FuciLxbzFrcuWya7JsMiJxaXMnce1xb7FsMiSyozLrMaIwpHLmcuwyp7LssKBxrdpxrllwqjGvcyBzIPLtMSPx7nCrcu5y7vEgsu-V8mqY8eXxLfEucONAzTEjsq_xL_FgcyKwrE8zI_Jh8WYxZoFzJrLgsycwoTLhsynxKnFnMuNxJrGhmHIgmzCoMubzZrNnMe5AMyrc8OAzaLNpMKgzK_GkcyxzLPMtcKlzYN0zYXNrMKVwpbGisSkAMSOaADHu8m-yJXHvsiAyIJyzb3Imc6BzoABa8WhyZ5nzovIos6OwonOkc6FzpPLmcu1zpYBzKnGhM6LZsSOzpfEjsKKAMWhZ8aOdcWSwpDCpsWObmZpZ8KAwqd2xq7Ev29uw4s_w5nCmc6-zr7Cmg"><em>click here to edit this workflow on eth.build</em></a></p>
<p>O bloco <strong>DECRYPT</strong>, como o próprio nome diz, faz o inverso do bloco <strong>ENCRYPT</strong>. Ele recebe como parâmetro a <em>private key</em> e <em>encrypted</em> (a mensagem criptografada no bloco <strong>ENCRYPT</strong>).</p>
<p>Private Key usada: <code>0x9c0257114eb9399a2985f8e75dad7600c5d89fe3824ffa99ec1c3eb8bf3b0501</code></p>
<p>Este bloco devolve como retorno a mensagem inicial descriptografada (<code>"hello word this is alice for alice"</code>).</p>
<h3>Full Encrypt/Decrypt Workflow</h3>
<p><img src="assets/screenshot_13.png" alt="/assets/learn-with-ethereum/screenshot_13.png"><br>
<a href="https://sandbox.eth.build/wofCrGxhc3Rfbm9kZV9pZMONAcKQxIHEg8SFbGlua8SLxI0BbcKlxIfEiXPCmMKKwqLEjMSOaMKkdHlwZcKrQ3LEqHRvL0jEg2jCo3Bvc8KSw6TDjMO5wqRzaXplwpJ4HsKlZsSCZ3PCgcKpY29sxIJwc2Vkw4PCpW9yxIlyAsKkbcSIZQDCpsSVcHV0c8KRwoPCpG5hbWXCpcWhxaPEpsSoZcKtxIRyxJVnLG51bWJlcsKkxJTElsSOScKnb8WjxaLFpMWmxajFqmXCpGjEs8WwxKnCpsW0xbbCpcaAa8WlxI5Lwqpwcm_EqXJ0aWVzwoDEocSjAWnGkGXCqkluxocvVGV4dMS1xLfCksOiw4zCvsS9xL_FgcSOLDLFhcWHxYnFi8WNxY_FkcWTxZXFl8W9AMWbxZ3Fn8WuxojFp8WpxavCoMaqx4zGlsOAxoTGhsWjxaXHksaLx5XEp8aRxpNuZ8aVxJXGl8KRxoLGm8adxp_GocajwoTCq2Jsb2NrxqJTxrwywqtwxIJjZWjFjcWYwq9lbnTFvSDIhsazIGjFvcWsxqF0bMaMxrHGs8KldmFsdcWsyJdpx77GpsSZwo3Gqsasxq7Fo8awxrLGtMS2xLjDjMOSxI5UxrvFgMKSxr7HgMWGYcWIwoDHicWYAceNxInHj8ijx5HGiseUx5bFv8enx5nGhXTGh8edyL9lx6DFscaSdMW1x6THpsSWxpgBaMerxp7Fvceuc8ewx7LHtMe2Zce4xYDHuse8Yce-yIBsyILIhMiGcsiIyKbIi8iNwqXIj8iRwqTIk3TIlciXyJnDmSLIjMWObyB3xZZkyIhoaXMgyoQgyJvHviBmxZbKiMSUyJ3EosSZwozGqsKuxKzErsSwRW5jxK1wyKfGtsONAhLEjgTIrsWBw4zCtC3Hgci0xqTIt8W9yqTFnMi7xaDIvcS4x57Fq8abdceyyJwga2V5xqrJjcmPZ8mCxoHGqMq1ZcKnxatzc8i0xozHoWXLgMW2y4NrxKTHmsmGx5zCksuGwqZvYmplY3TKv8uby53Ln8mRxpfDgMuGwqnIhMqbxK7Fksq_x6PHpcaWxLjEjmrEjmvJlsetxqLGpMiexI7Cj8aqwrBEyoTJo3nIpcazQXJlYca1y7ICw6TEjnzKpciwAcK4w4zClcqqyLXKrXIFyLrFnsqyyYfGiceTyYrLrsmOy5HGlsuzy5XMnsuGyYvHosyjyZDLscOAy7fJmMu5woHJsGnIkGXCqMm0zIbMiMu7AWvGqsKvypbKncSwS8q9IFBhaXLMisKSw4zDqMOMw5jKpcKCwqEww4pDU8KZwprCoTFCzJbKrMqAxb0DzJvIvMmHy5jJicKtW8acaciWyIbKu8q9Xcyiy4HLksaZy4bCqGfIhMW9YciGxqrDv8uSyYTHm8WkwpPLhse7xbXNq2XNrcq-y47LkMytx6fJk2zLhsq3yrljzofNsMaUy7HHqcuFyYnCp2FkZMyHy4rOlM6LyZLCkMywxqDLucalypHEjsKOypTNgcSvL0TLnsqcyp7Mi8O4w4zCqsyQyqfKqcizzJfNn3IGzaLMncuXzoLNqc6FzpPOicuvzbIBzo7JicupyprOscutz4bMrMuCzKXMvcynx5zMn8aLwqnEicuryp3Pj8mMy6LLnsm1zpbEjm3OpMmZzqfGp8KQxqrCrcyAc8yCL1fNuWPEtMioyLADw5TOtcyQxI7CsTzNnci2zrwHzr_HkMWlwoTJicyqxZ7PiMSbxILFvGzCoM-VxojQhMyg0IYAy6Vzw4DGlWHQi8Kgz6XMssy0zLbCpc-wdM-y0JTCmMKWxoLEjmkAxKQAxbPPkcW4xbrFvHLQpQFL0KrLtcWfy6_QsmjEjsKN0KkBwowBzopn0LJpy7UBxI7CjNC3z5HQssu00L7RhgHCj9GJy4HQssuT0Y3OqdGA0LjEjmzQts6p0ZHFttCybdGcxI7CkADFn2fGnXXFkMKQwqbFjG5maWfCgMKndsW9xL5vbsOLP8OZwpnRu9G7wpo"><em>click here to edit this workflow on eth.build</em></a></p>
<h3>Publish/Subscribe messages</h3>
<p><img src="assets/screenshot_14.png" alt="/assets/learn-with-ethereum/screenshot_14.png"><br>
<a href="https://sandbox.eth.build/wofCrGxhc3Rfbm9kZV9pZMONAcKZxIHEg8SFbGlua8SLxI0BdcKlxIfEiXPCmsKKwqLEjMSOaMKkdHlwZcKrQ3LEqHRvL0jEg2jCo3Bvc8KSLcORw79awqRzaXplwpJ4HsKlZsSCZ3PCgcKpY29sxIJwc2Vkw4PCpW9yxIlyBMKkbcSIZQDCpsSVcHV0c8KRwoPCpG5hbWXCpcWixaTEpsSoZcKtxIRyxJVnLG51bWJlcsKkxJTElsSOScKnb8WkxaPFpcWnxanFq2XCpGjEs8WxxKnCpsW1xbfCpcaBa8WmxI5Lwqpwcm_EqXJ0aWVzwoDEocSjAWnGkWXCqkluxogvVGV4dMS1xLfCkivEux_EvsWAxYLEjiwyxYbFiMWKxYzFjsWQxZLFlMWWxZjFvgDFnMWexaDFr8aJxajFqsWswqDGq8eNxpfDgMaFxofFpMWmx5PGjMeWxKfGksaUbmfGlsSVxpjCkcaDxpzGnsagxqLGpMKEwqtibG9ja8ajU8a9MsKrcMSCY2VoxY7FmcKvZW50xb4gyIfGtCBoxb7FrcaidGzGjcayxrTCpXZhbHXFrciYace_xqfEmcKSxqvGrcavxaTGscazxrXEtsS4ccSOB8a8xYHCksa_x4HFh2HFicKAx4rFmQHHjsSJx5DIpMeSxovHlceXxoDHqMeaxoZ0xojHnsi_ZcehxbLGk3TFtselx6fElsaZAW7HrMafxb7Hr3PHscezx7XHt2XHucWBx7vHvWHHv8iBbMiDyIXIh3LIicinyIzIjsKlyJDIksKkyJR0yJbImMiawr9zYW5kd8idaCBjaMida8iFIGJvdMiRZSB3b8qPypDIn8SOwpPGq8Ksxq7GsELFpMSvbsa2xLjDjMOVxI5ryK7FgsOMw4jIsseDxYvFjcWPYcWRxZPDgsi3xb4CyLrFn8WhyL3JiMeUyYrGq8O_yYLElsmEx5zFpcKSx5_JgMeiZcO_yZHHqcSOcMuCyrnLhMKuxbrFvMW-LMqIxY5lybvLh3PDgMmWx67Go3PCg8m2yJllwqhjxJTHtiDFrMmwacqLwqbKmcqKb27CpcWNdciGCMqSAcqiy4TCr8SsxK7EsEtleSBQYWlyyp3CksqfxLs9yqPCgsKhMMOKQ1PCmcKawqExQseCyLTGpcqwcsitxZ3Iu8q1yYfLgcmJwq1bxp1pyJfIhyDKhXldxqvJjcmPZ8q8a8aay4vCqGfIhcW-YciHyrrMsMq-yYbHncKTy4vHvMW2zKbKjMypzKzHpMemxpfJk2zLi8acdcezyJ3MqMu-zYbJjsaVzYnCkMuLwqdhZGRyxqRzzZPMrsuXwpDLmsmYy5zGpsSixJnCjsarwq7LunDEry9EZWPErc2uzIXEjsOczIjKo8yGwrQtzJbItcyZCMqzyLzMn82AzKTNg82Rec2gxbfMsMSOzYvJicKpyIXNs8SuxZPOiselzLvHm8y9yL7KuMKpxInOks2uzpTLhMKmb2JqzbLJtc2Jx6oBbc2kxqHNpsu1wpXGq8KxTmV0yo5yay9TzY5zzbNpxb3NtgHDrcSOwoDMisyMw4zDsMyTLs2-zJjFl8WZA86CzJ7HncaKzptbyoLJu25lbMyrzqHNh86XyYXOhMmJwqfFrHPJusy1zpXNiMeoyZNyzLPNnce_zKXOoMWyy4bNls6syZnCgsKnz5Zuz5hswrHPmM61xZdrLs60aC5idWnJp8Knz73OtmvDmciMyorFkTovL9CKz7_QgXTQg9CF0IdkOjQ0Mzg2L8u1wpDGq8KtRGlzyaN5L1fMuMqCzbYCwrLEu0LNusSOwrE8z4vIts-Nxb4Jz5DHkcWmwoTJicmLxKnHmMeoxI5txpZhxb1swqDOmMmHwpHRgcq40YPFn8uXw4DRidGLwqDPtMucwoHLqMqLwqXQrXTKgsKJzajEjsKRxqvCr86zz77Oty9QzY7ElHPEtMipyLABw5bDjMO6z4Uwz4fMk8yVyLPNv9C7cgXQvsq2zL_Oj8-Vxo_Puc-Zz5vJjM-dx5nNmM-jz6XGjc-czZTOlsaXxI5uzZjFo82P0bDMutKVAXDRmsakz7bPuM-6z7zOtNCL0JbQmNCG0IjQlM630I1o0I9z0JHQk9Km0JXQgtCE0qrQm9Cd0J_Qocu1wpfIosqXyKXJtM22AyrEjsKG0LUBx4DQucyZBtKC0Y_Li9GT0YXGggFy0Y7PktOQz6fRldKgyZrHsse0x7bHuMe6x7zHvsiAyILFvsiEyIbIiMiKdMmuzZ3RncmyybTLn8iaw5kveyLEryI6IsqIYiIsImbGnm3TuCLInMe_070iyJfLoNO4NdO-xIdu1IY6MH3Ll8KXwpbGg8SOaQDEpADFtNKTxbjLj8W9ctSWAUvUm8qhxaDNh9SjbNSnxI7CjtSo1J7Uo23UrdSaAcKQAADUo27EjsKS1LTCkQHMrcW31KNwypPUvQLDv9SjcsSOwpXUtMKX1LfCpmfGnnXFkcKQwqbFjW5maWfCgMKndsW-xL_LrsOLP8OZwpnVpNWkwpo"><em>click here to edit this workflow on eth.build</em></a></p>
<p>O bloco <strong>PUBLISH</strong> serve pra enviar uma determinada mensagem em uma rede, tipo um canal <a href="/posts/irc">IRC</a> (no caso a rede padrão é network.eth.build). E o bloco <strong>SUBSCRIBE</strong> é o bloco que recebe a mensagem. A cada envio no <strong>PUBLISH</strong> o <strong>SUBSCRIBE</strong> recebe automaticamente, de qualquer um que enviar uma mensagem.</p>
<h4>Encrypt messages on the network</h4>
<p><img src="assets/screenshot_15.png" alt="/assets/learn-with-ethereum/screenshot_15.png"><br>
<a href="https://sandbox.eth.build/wofCrGxhc3Rfbm9kZV9pZMONAcKlxIHEg8SFbGlua8SLxI0BwoLCpcSHxIlzwpvCisKixIzEjmjCpHR5cGXCq0NyxKh0by9IxINowqNwb3PCksOMwoPDjMKwwqRzaXplwpJ4HsKlZsSCZ3PCgcKpY29sxIJwc2Vkw4PCpW9yxIlyBMKkbcSIZQDCpsSVcHV0c8KRwoPCpG5hbWXCpcWixaTEpsSoZcKtxIRyxJVnLG51bWJlcsKkxJTElsSOScKnb8WkxaPFpcWnxanFq2XCpGjEs8WxxKnCpsW1xbfCpcaBa8WmxI5Lwqpwcm_EqXJ0aWVzwoDEocSjAWnGkWXCqkluxogvVGV4dMS1xLfEucKBdcS-xYDFgsSOLDLFhsWIxYrFjMWOxZDFksWUxZbFmMW-AMWcxZ7FoMWvxonFqMWqxazCoMarx4zGl8OAxoXGh8WkxabHksaMx5XEp8aSxpRuZ8aWxJXGmMKRxoPGnMaexqDGosakwoTCq2Jsb2NrxqNTxrwywqtwxIJjZWjFjsWZwq9lbnTFviDIhsa0IGjFvsWtxqJ0bMaNxrLGtMKldmFsdcWtyJdpx77Gp8SZwo7Gq8KuxKzErsSwRGVjxK1wxrXEtsS4w40CMsOMwpPGu8WBxLnCtC3HgWHFicKAx4nFmQfHjcSJx4_Gr8ecwpLHnsWsx7vFtsiWyIYga2V5xqvGk3TFtsekxoDHp8SObMmFZcKpyITIqMSuxZPJj8ejZ8mUxJbHmcaGdMaIx53Gi8WswqnEicmcyKrJnsehZcKmb2JqyKd0x6bElsaZAW3Hq8afxb7HrsalyJ7EjsegxbLCrMauxrBCxaTEr27GtsitAwPIrsa6xL_ItMOMw4jHgMWHyLnHg8WNxY9hxZHFk8OCyLzFvgHIv8WfxaHJgseRyallyoTEqcO_yaJryaTHm8WlyYTKqcqrZcO_ybjHqMSOe8mYyrXCrsW6xbzFvixib8WOZWFuyrhzw4DJvcetxqNzwoPIlciXyJnCqGPElMe1IMWswqXIj8iRwqbKiXTKi8KlxY11yIURyoIBa8arwq_Io8iqxLBLyY0gUGFpcsqNwpLEjivIscizZcKCwqEww4pDU8KZwprCoTFCyLjIusqhcgbKpMmByafKs8eTxbNbxp1pyYllyYvJjV3Jn8mRxbfKrsaayZjCqGfIhMW-YciGxqvKrceYx5rJpsecwpPJmMmHzJTMpMyWyYzJjsmwyZDJkselxpfJusmXyqnGnHXHssiczJfMs8WyzLXGlcy4x6kBf8mYwqdhZGRyxqRzzJrMtsuJwpDLjMm_y47CgMKJxKLEmcKey6lOZXR3xZdrL1DMvcSUc8S0yKzLtgQIxI7Dr8u6y7www4zDsMyEzIbKmMyIxZfFmQrMjMqmyafMrMqpwqlbY8aPbm5lbMyZzLTJoMquw4DNicWsc3PIucaNzorMm8mTxpfEjn7NicWjzL7NqMymzJ0Be82VxqHLjsKCwqfOg8uHzoZswrHOhs2gzaIuzZ9oLmJ1aWxkwqfOrM2hcmvDmciLy5_FkTovL865zq7OsM6yzrTOtjo0NDM4Ni_LpsKhyKHLq8SvL0Vuya3Iq8a3yK7DrsSOw7TLusi1yLfNt8alzIkIzbzHkMS4yZjMvMy-Y82AzZHMnM6XzYfOjs2PzpLPr86WyZUBfcypzI7JmMmyybTJtsmPybPJtWPJt8y4zo3OgMmbyKnIhmTPtsy3x6fJun7OosqAxqbNmsSOwp_Gq8atyqfGscazz5rIrQHCsciuwpbPoMa-ypfHgsWLypvHhsWTxZXNucW-As-nyqfJqMyQyrXHl8enyrDMqsqo0LLQjcuJzYZ90JLLjsewx7LHtMe2Zce4xYHHuse8Yce-yIDOtsW-yIPIhciHyIl0yIvIjcuaaciQyJLQnMuRyJhlwrh0aGlzINGgIMadybNhx7LMlsWSyKjNnyDLpsKlxqvCsETRoNGIedCbxrRBzY5hy7XDjMKMxI7CuNCjAcK4w4zClcyHz6TQrHIF0K_Jp8aK0LnOlMy2zp_Opcml0ovKvNC60IbQvsakwoHRldGXwqjIk3TRuMuGy6bCkMarwq3RsnPRtC9XzKTOg8u1w40DDMOM0KLKk8a90J880oXIu9KHCdKKx5zCkcKEyrTHls6fbcaW0afOh8Kgz7vSu9K90o3FsgDLicOA04LFvWzCoNKXxYrSmsiRwqXSqXTOg8umwqPGq8KxzZ7Orc67L1PMvXPIqGnFvdG7wqDEjkrNsMu9zbPMhC7ShdCnx4XKnceHyqDShwPSutC4xozOgc6nzoXOh86JzYLOi8yo0pLJg8-zzpDPtdKOzYTQj82GwoLMn82Ox77MlMmvxbLKt9KW0aXLjcakzqXTvc6pzqvNn866a86v0Z7Ph861zrfPhM67zr1ozr9zz4HPg9Sdz4XUoc6z1KPPis-Mz44vy4nCmcKWxoPEjmkAxKQAxbTOlcW4yr_FvXLUuAFL1L3EjmvFoMmg1YVs1YnUvAHCjtWL1YDVhW3EjtWSxI7CkAAA1YV7yoPVkMKeAsO_1YV90JbVkMKhAc2Dx6TVhX7EjtWoxI7CntWp1YzEjn_ViQHVrtWTzLbVhcKCxI7Co9WQwqXVucW3wqZnxp51xZHCkMKmxY1uZmlnwoDCp3bFvsS_b27Diz_DmcKZ1pnWmcKa"><em>click here to edit this workflow on eth.build</em></a></p>
<p>Aqui podemos combinar os blocos <strong>ENCRYPT</strong> e <strong>PUBLISH</strong> para enviarmos uma mensagem criptografada na rede. E depois obtermos a mensagem criptografada com o <strong>SUBSCRIBE</strong>: <code>0xf0565fb9b8d0ce71b5886c71dfad9803020bd4e8329e66b63b93703283f6e6dbae5c181458a166966a5a70bedc96f3f3ad52261ab619ee312ff5979af11cc4f0eeb0c9af9baeb6b3dd66af72c97a371482066a5cd40e11bf24d4f469416b27831c03189b3e07b3c5a8044ca95392b1d5c9</code></p>
<h4>Decrypt messages on the network</h4>
<p><img src="assets/screenshot_16.png" alt="/assets/learn-with-ethereum/screenshot_16.png"><br>
<a href="https://sandbox.eth.build/wofCrGxhc3Rfbm9kZV9pZMONAcKlxIHEg8SFbGlua8SLxI0BwoPCpcSHxIlzwpvCisKixIzEjmjCpHR5cGXCq0NyxKh0by9IxINowqNwb3PCksOMwoPDjMKwwqRzaXplwpJ4HsKlZsSCZ3PCgcKpY29sxIJwc2Vkw4PCpW9yxIlyBMKkbcSIZQDCpsSVcHV0c8KRwoPCpG5hbWXCpcWixaTEpsSoZcKtxIRyxJVnLG51bWJlcsKkxJTElsSOScKnb8WkxaPFpcWnxanFq2XCpGjEs8WxxKnCpsW1xbfCpcaBa8WmxI5Lwqpwcm_EqXJ0aWVzwoDEocSjAWnGkWXCqkluxogvVGV4dMS1xLfEucKBdcS-xYDFgsSOLDLFhsWIxYrFjMWOxZDFksWUxZbFmMW-AMWcxZ7FoMWvxonFqMWqxazCoMarx4zGl8OAxoXGh8WkxabHksaMx5XEp8aSxpRuZ8aWxJXGmMKRxoPGnMaexqDGosakwoTCq2Jsb2NrxqNTxrwywqtwxIJjZWjFjsWZwq9lbnTFviDIhsa0IGjFvsWtxqJ0bMaNxrLGtMKldmFsdcWtyJdpx77Gp8SZwo7Gq8KuxKzErsSwRGVjxK1wxrXEtsS4w40CMsOMwpPGu8WBxLnCtC3HgWHFicKAx4nFmQfHjcSJx4_Gr8ecwpLHnsWsx7vFtsiWyIYga2V5xqvGk3TFtsekxoDHp8SObMmFZcKpyITIqMSuxZPJj8ejZ8mUxoLEmseadMaIx53Gi8WswqnEicmcyKrJnsehZcKmb2JqyKd0x6bElsaZAW3Hq8afxb7HrsalyJ7EjsegxbLCrMauxrBCxaTEr27GtsitAsKdxI7DnMizxYLDjMOIx4DFh8i5x4PFjcWPYcWRxZPDgsi8xb4ByL_Fn8WhyYLHkcmpZcqExKnDv8mia8eZxobJpsmDyZjKq2XDv8m4x6jEjnvKtMihxbrFvMW-LGJvxY5lYW7KuHPDgMm9x63Go3PEm8iWyJhlwqhjxJTHtSDFrMKlyI_IkcKmyol0yovCpcWNdciFEcqCAWvGq8KvyKPIqsSwS8mNIFBhaXLKjcKSxI4ryLHKk8KCwqEww4pDU8KZwprCoTFCyLjIusqhcgbKpMmByafJhMqpwq1bxp1pyYllyYvJjV3Jn8mRxbfKrsaayZjCqGfIhMW-YciGxqvKrceYyaXJp8KTyZjJh8ySzKLMlMmMyY7JsMmQyZLHpcaXybrJl8qpxpx1x7LInMyVzLDFssyyxpXMtcepAX_JmMKnYWRkcsakc8yYzLPLiMKQy4vJv8uNwoDCicSixJnCnsuoTmV0d8WXay9QzLrElHPEtMisy7UDwqLEjlbLucu7w4zDsMyCzITKmMyGxZfFmQrMisqmzKjJmMKpW2PGj25uZWzMl8yxyaDKrsOAzYbFrHNzyLnGjc6FzJnJk8aXxI5-zYbFo8y7zaXMpMybAXvNksahy43CgsKnzb7Lhs6BbMKxzoHNnc2fLs2caC5idWlsZMKnzqfNnnJrw5nIi8uexZE6Ly_OtM6pzqvOrc6vzrE6NDQzODYvy6XCkMarwq1EaXPHvGF5L1fMos2-y7TDjQMMw4zClsqTy7UBwrE8zIXGpcyHCc24x5DFpsKEyqnKtceXyZXJu8aWYcW9bMKgzKfHnMKRz6zHk8qqx5bLiMOAz7LPtMKgzp3KgMKBy5lpyJDFrc-XdM2-y6XCo8arwrHNm86ozrYvU8y6c8ioacW9y7RQw4zDps2tMM2vzIIuz6XFi8qbx4bFk8WVzbXFvgPPqcqnyajPu828zqLOgM6CzoTMv86GzKbKscyMzonNjM6NzY7NgcenybrCgsydzYvHvsySya_Fssq3zLXLisadyb7OnsakzqDQss6kzqbNnM61a86qdM6szq7OsM6yzr_Ots64aM66c868zr7RlM-A0ZjPgtGbz4XPh8-Jz4vNl8SOwqXGq8Kwz5DPksSCz5XIk3RBzYthy7RaxI4iz6DEjsK4w4zClc-lyLvQqnIF0K3Jp8aKz7vKtc2AzpHPsM6g0LnPuMq8zo_Nj82CxI7Cg9CDy43Qhcuay5LRt9G5y4XLpcKhyKHLqsSvL0Vuya3Iq8a3yK7CisSOXs-gw4zIttKFzIcI0orKs8y4zpbLlcy90L7SkMmjzYXKqcKnzorOjMyf0r7Joc6SAX3Pt8WlzI3Pu8myybTJtsmPybPJtWPJt9GKzbvJm8ipyIZk04fLiM2DftKbxqTGptGuAcKfxqvGrcqnxrHGs9KsyK0BSsSOw77SgAHGv9Ckx4TKnMqeZMqg0ocC0rjKqNKNx5bOh9OM0K_Hn9Oe0pjTitOic8ewx7LHtMe2Zce4xYHHus-Tx77IgM6xxb7Ig8iFyIfIiXTIi8iN0IbQiMKk0bfIlciXyJnCuNGYz5Eg1KjRjGLPs8iRIMWSyKjNnCDLiMKawpbGg8SOaQDEpADFtM6QxbjKvsW9ctS2AUvUu8SOa8WgyaDVg2zVh9S6AcKO1YnUvtWDbcSO1ZDEjsKQAADVg3vKg9WOwp4Cw7_Vg33EjsKf1Y7CoQHSj2fVg37EjtWnxI7CntWo1YrEjn_VhwHVrdWRzLPVg8KCxI7Co9WOwqXVuMW31YPCg9Gv1Y7CjtWx1L7CpmfGnnXFkcKQwqbFjW5maWfCgMKndsW-xL9vbsOLP8OZwpnWn9afwpo"><em>click here to edit this workflow on eth.build</em></a></p>
<p>Combinando o workflow anterior com o bloco <strong>DECRYPT</strong> conseguimos descriptografar a mensagem enviada na rede.</p>
<hr>
<h2>referências</h2>
<p>Austin Griffith: <a href="https://www.youtube.com/playlist?list=PLJz1HruEnenCXH7KW7wBCEBnBLOVkiqIi"><em>https://www.youtube.com/playlist?list=PLJz1HruEnenCXH7KW7wBCEBnBLOVkiqIi</em></a></p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>blockchain</category>
            <category>hash</category>
            <category>cryptography</category>
            <category>tool</category>
            <category>asymmetric-cipher</category>
            <category>chat</category>
            <category>ethereum</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/learn-with-ethereum-2/thumbnail"/>
        </item>
        <item>
            <title><![CDATA[Learn With Ethereum]]></title>
            <link>https://mateusf.com/blog/post/learn-with-ethereum</link>
            <guid>learn-with-ethereum</guid>
            <pubDate>Fri, 11 Dec 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[Desenvolvendo alguns algoritmos de criptografia e hash no eth.build]]></description>
            <content:encoded><![CDATA[<p><img src="https://mateusf.com/blog/post/learn-with-ethereum/thumbnail" alt=""> {/* Workflows \ */}</p>
<p>{/* Workflows */}</p>
<p>Primeiros passos em <a href="https://eth.build">eth.build</a></p>
<h1>Hash Functions</h1>
<h2>Generating the hash color of...</h2>
<h3>... a string</h3>
<p><img src="assets/screenshot_1.png" alt="/assets/learn-with-ethereum/screenshot_1.png"></p>
<p>O input principal é o bloco <strong>TEXT</strong>, no qual está sendo usado o valor "Hello Word".</p>
<p>O bloco <strong>HASH</strong> está pegando esse valor de <strong>TEXT</strong> no seu <em>input</em> e esta retornando como <em>output</em> uma <em>hash</em> <a href="https://github.com/ethereum/eth-hash">keccak256</a> (eth-hash).</p>
<p>O bloco <strong>STRING</strong> esta exibindo essa <em>hash</em> como uma <em>string</em>. O bloco <strong>LENGTH</strong> esta exibindo o tamanho dessa <em>hash</em>.</p>
<p>O bloco <strong>SUBSTRING</strong> está pegando essa <em>hash</em>, e esta fazendo um tratamento de extração de uma <em>string</em>, usando como parâmetro o <em>start</em>, que determina a partir de qual índice da <em>hash</em> original será feito o tratamento, e o parâmetro <em>length</em>, que determina a quantidade de caracteres extraídos. O bloco esta retornando como <em>output</em> a <em>string</em> extraída de 6 caracteres a partir do terceiro carácter da <em>hash</em> original, como estipulados nos parâmetros.</p>
<p>O segundo bloco <strong>STRING</strong> esta exibindo o <em>output</em> do <strong>SUBSTRING</strong>, e esta envidando para o bloco <strong>COLOR</strong>, que por sua vez esta exibindo uma cor baseada na <em>string</em> recebida como um hexadecimal.</p>
<h3>... a file</h3>
<p><img src="assets/screenshot_2.png" alt="/assets/learn-with-ethereum/screenshot_2.png"></p>
<p>Os mesmos passos que com uma <em>string</em>, porem substituindo um bloco <strong>STRING</strong> por um bloco <strong>FILE DROP</strong>. O bloco <strong>FILE DROP</strong> recebe um arquivo como <em>input</em>.</p>
<h3>... combinations of hashes</h3>
<p><img src="assets/screenshot_3.png" alt="/assets/learn-with-ethereum/screenshot_3.png"><br>
<img src="assets/screenshot_4.png" alt="/assets/learn-with-ethereum/screenshot_4.png"></p>
<p>Aqui estou usando o bloco <strong>COMBINE</strong> para combinar as <em>hashes</em> anteriores e gerar uma nova cor com o mesmo processo.</p>
<p>Qualquer mudança no <em>input</em> inicial de qualquer um dos 3 blocos <strong>TEXT</strong> irá alterar tanto o resultado daquele <em>workflow</em> em específico, quanto o do resultado usando o <strong>COMBINE</strong>.</p>
<h1>Key Pair</h1>
<p><img src="assets/screenshot_5.png" alt="/assets/learn-with-ethereum/screenshot_5.png"></p>
<h2>Generate fingerprints</h2>
<p><strong>KEY PAIR</strong> é um bloco que consegue gerar uma <em>private key</em>, uma <em>public key</em> e um <em>address</em> baseado em um <em>string</em> aleatória (neste caso quem ta gerando uma <em>string</em> aleatória é o bloco <strong>BUTTON</strong>).</p>
<p>Private Key: <code>0x7eed612b561d9a7a738bd009a810577fd7023842b481b7523af95aa50350dd16</code></p>
<p>Public Key: <code>0x299be7653d60ae3f8a6e5bf003c3989eb626e0f5e4240bae1cd0914da17b441960f99ec90445fbd4e5566b6dc0856ff167fdf65f128eb697a9995fe8ba459da7</code></p>
<p>Address:</p>
<p><img src="assets/screenshot_6.png" alt="/assets/learn-with-ethereum/screenshot_6.png"></p>
<h2>Sign a message</h2>
<p>O bloco <strong>SIGN</strong> vai usar como parâmetro de <em>input</em> uma mensagem, no caso "the bear is stick with honey", e uma <em>private key</em>. A partir disso ele vai gerar uma assinatura como <em>output</em>: <code>0x21fa2503c40eab0c53ef362c79b2b84e8cb9b46bb3c4db8cd981394461ce4a32515f17c0d7ed62bb52fdd2a1c09fe22973cefaed8fd98bdcb852a125ffacd4711b</code></p>
<h2>Verify a message</h2>
<p><img src="assets/screenshot_7.png" alt="/assets/learn-with-ethereum/screenshot_7.png"><br>
<a href="https://sandbox.eth.build/wofCrGxhc3Rfbm9kZV9pZMONASPEgcSDxIVsaW5rxItkw4zDvsKlxIfEiXPCncKKwqLEjMSOHsKkdHlwZcKqSW5wdXQvVGV4dMKjcG9zwpLEjkrDjQPCosKkc2l6ZcS6ASwywqVmxIJnc8KAwqVvcsSJcgDCpG3EiGUAwqbElcSudHPCkcKDwqRuYW1lwqDEpsSoxZjCpMSUxJbDgMKnb8SvxZzFnsWgxaLFpMWmxKfEqcKmxIRyxJVnwqXFq2vFnsOMw7nCqnByb8SpcnRpZXPChMKrYmxvY2vGi1PFgmUywqtwxIJjZWhvbMWSwq9lbnRlciDGpsS0IGjGp2XCpcaKdGxlwqTEssS0wqV2YWx1ZcK8dMatIGJlYcaoaXMgxIRpxpMgd2nGv8asb25lecShxKMBH8WnxKnEq8StxK_EscSzxLXEt8S5xLvDjQQQxYDGl8WFxYfFicWLxY3Fj8WRxqcBxZXFl8WZxZvEr8WyxaHFo8Wlx5nFqcW_xa3Fr3TFscWfx7jFtce7xbl0xbtuxb3Fv8aBw7rGhMaGxojGisaMxo7GkMaSxpRlxpbFg8aZxpthxp3Gn8ahxqfGo8alxqfGqcefxqzGrsawx47Gs8a1x5_GuMa6xrzDmcKEMHgyMWZhMjUwM2M0MMeDYjBjNTNlZjM2MmM3OWIyYjg0ZThjYsmMNDZiYsi7NGTJj2NkOTgxMzk0yZcxxp00YTPIuDE1ZjE3YzBkN2VkyYjJmTUyZmRkMmHJqDA5ZsaYMjk3yLvJhWHJtzjJvcmhYmTJlDjJu8qByLhmyLbJnzQ3MTFix5XEjQEVx7vCsETHhsibeceexLRBcseDxLbEuMS6AsKEw4zDhcenxYPFhUBkx6thxYzCgcKpY8agxIJwc8m3w4LHrsWSCseyxInHtMecxZ3IgsW0x7rFt2XIhsiIZ8WqxJVrw4zDsMWuxbDHtsuPx7nFtsWoy5TFvMW-y5hzw4DIjsaHxqfIkXPCgcioxrJlwqjGtnTKrMeDwonEosqhFse7wq_KpnPKqC9Byb7KrXNzyq_HogLCjsSOW8q2xYTEjlRQyrvKvcq_y4Fhy4PLhcuHxqcLy4rFmMWay43Ht8uQy6HEqcWUxb_DjMOxy6nIkMaLc8KDxo_GkcaTxpXGl8iaxpzGnsagxZLCoMuvxrPCp8yBZMyDc8qgxI4Zx7vHm8WcyqrHoMqwxI4mw40CBcyMx6nFiMWKyrzHrcWQxZICzJvLjMiBxbPLoMe7zKPLmMe-y53Ljs2YyITLksujyInLpcSWxoHDtcyny6vMqciTzK3IlsiYxpjGmsyyyJ7GosakxqbGqMaqdMimyq3Mt8a0y7PIrca7xr3Gv2XHgceDx4XHh8eJx4vHjcePxp_HkseUy7jEjhzKpMu9y7_Ls8u1YcyGxLoDwojNic2LxYHKt8SOyrnMkc2Rx69yDM2VzJ3Nl8iDy5HLosW6xbzLl8SWw4zDuMucyIDLns2gzqvFuM6tzaTIi8uoxoXLqsaJzKnLrsaxxrPLssefzpbMvgEPx7vCrMSszYNCxK90x5HOmG7EjiLNjMOMw4jNjsesyr7LgGzLgsuEZMODzJhyA86nx7XNn86qzKFlw7_Or2vNnc60xZ3Cks62z6nDv82lxoDCkcOMw6vPsse7wq5udW3HgnIsYm_GoMeDbs-1y6fNqc6_xozCg82_xrzCqGPElMeLxaTNvMKmz450z5DQh8uAdcalFs-HDsu7Q3LEqM-QL0vHkyBQYWlyzpjEjjbLmsyMwoLCoTDDikNTwpnCmsKhMULOos-bzJTMlmTLhs2SxqfNi8WWy4vOqMe2z7HOqsKtW8aFaca5xqYga8eTXciFzrnLlse9zrbCqGfGpManYcamx7vPq8ykw6vOs8WxwpPOtsaaxbvRkc6D0ZR50ZfIh8ukyIvCksOMw6zDjMO0zrbGhHXGkMeK0ZPHk9Gwy5XQiM-3w7DOtsKnYcyCxoxz0oDRssumz7fMps69zKjGjMKAz4cRx7vCrc6TxILKqVfRoGNo0K4CMMOMwoLNjMS9MTzQvsyTz53Mlc-fz6HRhHIIz6XMnsKRwoTPqM2az6zRtcW-YceCbMKg0abLntK0zKDNmtCIwpDSudK7wqDQisusz4HIqcav0pt00p3PhxfHu8Kr0KLQpG8vxpZnbtKfzIkBw53QstC00LY6ypjQu1bOosWO0q4J0rHFscKUzrbCrNGO0avRoGXRrtGWzaLRmNK30bjOqsKq069vdsSMxqfTtM6s0bHIic-sw4DOtsKpW8WkzITKvGXUgM641ILRmcuYw4zDtc62x6fTmdGi1ITSvsWd06zOqtKG0ojMhNKLzrrLpsKQ0oXUiXPUi9SgyIrLptSFzqrCqcWB05nRoHXKrdSo0oLOsc62xblp05nJt9Gi04PTiMypwoXCp9Sl1IvGvseAx4LHhCDHhseIxorOiceOaMeQzo3IjtGQ07HQp3nDmULIssm2ybc2McmONdWayaBhN9WgMzjKkTDKg2HJojA1NzfJvTcwMtWjNMmONMmiYjfJuzNhZjk1YWHIuTPIucm-MTbCqM69073FksK7aNCYy4M6Ly9ycGMuZca_LmJ1acahOsmX1bE01K3UuMWidNSxZcOAwqhhxK9v05huw4PPhx3Pu9OUcNClUmXLgHbGp9Kfwp7EvcOK05_QtUMhMzPQuy7Tps-iBNOq0YrUhtSI0onUi9SNy5PTtsykw7nRqVvUrtaj1qXXj82j1JDOsMO61JnMn8e51J3Mu9KJ1LPRs8OMw7vDjMO91L3GjMKC1YDXjdGd1YPOg9WFzobViceKa8eM1YzVjseT1qHUr9akyq3IsMiyyLTItsi4yLrIvMi-0rrJgcmDyYXJh8mJyYvJjcmPyZHJk8mVYsmXyZnJm8mdyZPJoMmiyaTJptWayanJq8mtya_JscmzybXVmcmOYsm7yb3Jv8qBybPKhMqGyojKisi2yo3Kj9WkypLJj8qV1ZvJr8qZZMqbyp3Kn86PASDSltKYYdKa0pzSnsehzplcxL3StM6ezI0CEdKnzY_FjNOnzqQG14nLjtOAzZnLks2bzrDDu9OFZdK8157Ss9K12ZvQiMOA2Z_SvNeqy63NvMKl043Sncu3x5bPlcuSy7zKp9KZzIDUnsyF2YjEvWbEvcO80qQBzI_XhtKuB9mX15_NocWo2ZzLmdep0pDNqtCMzKzIlcyvyJnNsciczLPIn3LMts-CZcy52bjQiMKbwpbPuMSODwDEjg4Bw7_an8Os2qTaowERAADan8Ow2qQBxI4VxZnRmNqfw7HapALEjhbartqfw7TaqsSOF9q21I_an8O1zL_aqxcC15ran8O424LauwEc24TLldqfw7nEpNqrHduTxbzan8O6xI4f25gB24zXpsSO25nEjiDavteo26TaqyLarsKmZ8aGdcuDwpDCpsuAbmbUuMKAwqfWuHLFgceRw4s_w5nCmdyC3ILCmg"><em>click here to edit this workflow on eth.build</em></a></p>
<p>O bloco <strong>RECOVER</strong> é capaz de pegar a mensagem e a assinatura, e verificar se a assinatura é válida de um determinado endereço.</p>
<h1>Send and Receive values</h1>
<h2>Create a receiver address</h2>
<p><img src="assets/screenshot_8.png" alt="/assets/learn-with-ethereum/screenshot_8.png"><br>
<a href="https://sandbox.eth.build/wofCrGxhc3Rfbm9kZV9pZMONAUbEgcSDxIVsaW5rxIvEjQEkwqXEh8SJc8KaworCosSMxI5BwqR0eXBlwqpJbnB1dC9UZXh0wqNwb3PCksSOwq7EjsOgwqRzaXplxLoBLDLCpWbEgmdzwoHCqWNvbMSCcHNlZMODwqVvcsSJcgDCpG3EiGUAwqbElcSudHPCkcKDwqRuYW1lwqDEpsSoxaHCpMSUxJbDgMKnb8SvxaXFp8WpxavFrcWvxKfEqcKmxIRyxJVnwqXFtGvFp8SOIsKqcHJvxKlydGllc8KEwqtibG9ja8aUU8WBZTLCq3DEgmNlaMWQxZvCr2VudGVyIMauxLQgaMavZcKlxpN0bGXCpMSyxLTCpXZhbHVlwrdodHTFkzovL2RhaS7Et2EubmV0d8WZa8ShxKMBPsWwxKnCrFdlYjMvQseCYW7GpsS2xLjEugNIxL3Ev8agwoLCoTDDjMOSwqExQsWIxYrFjMWOxZDFksWUZMOCxZjFmsavBsWexaDFosWkxK9zwpPFvMWsZcKnYWRkcsaVc8efZcaCdMaEbmfFs8SVa8SOGsiQxa3CrFvGmcaba2Nox49uXciayJzInsigxojGi8imxrfIrWXGnMiaw7_IocSWxI4gxbfFuciNwpHChMWqyJHCp2LHqMeqxrzGgMibbnVtYsavxofIosaKASPGh2HJlGzCrjg0MTU1NjDJpsmnyabGjcaPxpHGk8aVwoLIk8iVyJdzc8OZKjB4MzhiNDhhNmE4ZTdiNmMxZjkwNjTJozNjNGVhMmNjNTMyZDNkMjlmY8Koxo5vdsSMxq_HhseIx4rHjMeOx5DHkseUx5bHmHLHmsSixJlFyJrCrlXGk2xzL0bGj20gx6Jpx6zEucONBHTHscWAxYLHtMe2wqDHuRrHvGHFi8KAyIXFmwjIicSJyIvErcmFyLjCpciMdMiawq3JkcmTxq8sxoPGhci_yKPJmcmDx4nLmsmIxa3CpsW4y6vLnsmPwqbLocmUcsmWxJbJmCTJqsaQxq_JrcWMwqjEiWNpbceCcxLHm8SZQsiawqzErMWlx6bEr3RvbsuCxYTEvAISx7LFgsKSw4zDiMWHxYnLkMe-xY_FkWHFk8WVxZfFmcWbAcuWxaHFo8uZxabFqMutxa7IvcunxbbLsMW6wpLIuMW_xbHDv8u4xonCkcmBzLrKtcu1y6Nib8WQypFuzL5zw4DLvMmsxpRzwoPHgMeCx4TCqGPElMacIMWtxrhpxrrIm0LMkcyTwqXFj3XGrR7MicSOLciaxKvMr8SxxLPEtcS3xLkexI4OzJrFg8SOxYbLj8WLxY3Mo8iBzKfLk8avAsysy5jFusyxxb3Ms8mPxZ3GiMy2yYTMsM2Cy7PLpcifzYvNgAEIzY7Lvs2QxpfIqsacxp7GoMaixqRhxqbGqGzGqsasxq7GsMaydMa0xrbNnM2exr3Nr82Tx4NlwqzNhnfJrWbGhMeOec2oxJrImsKrQ3LEqMySL0jEg2jMlcSOSs20zbbCkngezbrMosiAzKXIgsyoyIZyA86DzK7Ohcuby53Ln86RZyzNhHLLp8SOCMuqz5vMssKkyK5zaMiyz5_Ok8SOBc6XxpLNkMKAzrwlyJrCr8-Az4JvL0tleSBQx49yz4jMmMOMw7DNtsuKw4pDU8KZwprHuce7zKDNu8e_zKTMpsiDzoByBM-Zy53Euci4wq1bxo5px4HGriBr0IDIsc6QyJ3Lpsi2AQXIuMKoZ8asxq9hxq7MtM6Lz6fIjciPzLLGo8aE0KRl0KbQgM-u0KvOksaIc8KQyLjGjXXGmWlj0YF50YPItM2L0YjMssmwyJbImNGRxoXNi8KTxI4TyKTEjiHPs8u_woDCicqyxI45z7lEaXPOoHkvQcmxyJjPiAMgFM-MxI5UUM-QzbzPktCXyITMqcavBdCczK_Fu8yyzLvEqc6KyKLRndGizZDCg8aYxprOnGXGn8WCzp_GpcanxqnGr8Kgzq3Gu8Kn0bDRl8mz0aXHnETNq9Gq0azEgtGuUVLPiAVaRtG3AcKQxI7CkNG70JXNvsWW0JkH0oPOhcmHzofSh8Wy0K0hyZvJncm1ybfJucm7yb3Jv8qByoPKhcqHyonKi8qNyo_KkcqTypXKl8qZypvKnWPSjMmuwqZxctKTZcSOGMmWZ8eHw4LOvNKuyY_Cr9Kl0a0vRM-ScnPSq82zAljPjMOMwr43z5DLktKAcgnSusus0r3ImtKJyYDEmtC5zo7Shsiyz6LNi82NyqHNj8aVzprSkMad0pLOnsaj0pbOo86lxq3Gr8axza_Oq8iX0pvIktOuzKTTsM6xx4TDiz8WD8KWMsO4SMO-zYvCmcKWz7HEjiQAxI4lxaLPn9SxzpXNqdS1xJoAwq3Pn8-hyZLLttS60Z4BJQLRpwAA1Loa1LbViced1LjRhGfUuiDEjkLUvT4Cw7_UuiHVj8SORNWL1LoixKTVmQHIs8aF1LojxI4-1L1F1L_Posuk1ZPUuiTEjtWvxI5G1YvCpmfGj3XFk8KQwqbFj25maWfCgMKndsavxYDMk9Smw5nCmdaP1o_Cmg"><em>click here to edit this workflow on eth.build</em></a></p>
<p>O bloco <strong>HASH</strong> recebe um texto ("bowtiefriday") e devolve um <em>hash</em>, o bloco <strong>KEY PAIR</strong> recebe essa <em>hash</em> como uma chave privada e devolve um <em>address</em>.</p>
<p>O bloco <strong>QR</strong> exibe um <em>QR Code</em>, esse <em>QR Code</em> será o usado para receber transações.</p>
<p>O bloco <strong>BALANCE</strong> recebe como parâmetro o endereço de uma rede <em>blockchain</em> existente e o endereço, e devolve o balanço monetário atual disponível para aquele endereço. O bloco <strong>FROM WEI</strong> converte esse valor do tipo <em>string</em> para o tipo <em>number</em>, e o bloco <strong>DOLLARS</strong> pega ess número e formata como um valor monetário em dólar.</p>
<h2>Send values</h2>
<p><img src="assets/screenshot_9.png" alt="/assets/learn-with-ethereum/screenshot_9.png"><br>
<a href="https://sandbox.eth.build/wofCrGxhc3Rfbm9kZV9pZMONAWXEgcSDxIVsaW5rxIvEjQFGwqXEh8SJc8OcAB3CisKixIzEjj7CpHR5cMSQV2ViMy9CYcSCbmNlwqNwb3PCksONA0jEjsOgwqRzaXplwoLCoTDDjMOSwqExQsKlZsSCZ3PCgcKpY29sxIJwc2Vkw4LCpW9yxIlyFcKkbcSIZQDCpsSVcHV0c8KTwoPCpG5hbWXCp2FkZHJlc3PEqMSqZcKmxIRyxJVnwqTElMSWxI4axbHFs8W1wqxbYmxvY2tjaGHElV3Fv8SrxoJ0xoRuxobGiGvEjiLGjMW0ZcKlxpZlxpTGm2XDv8aHxJXGowEgwqdvxa3FrMWuwpHChMWyxqfCp2LEs2HEtWXGrcKmbnVtYmVywqXGonPCkcSOI8eMYceJbMKuODQxNTU2MMedx57HncKqcHJvxKtydGnFvMKCxbfFucW7xb3DmSoweDM4YjQ4YTZhOGU3YjZjMWY5MDY0x5ozYzRlYTJjYzUzMmQzZDI5ZmPCqMeib3bEjMeKwrdodHTFmjovL2TGmC7EuWEubmV0d8Wga8SjxKUBRcatwq5Vx6dscy9Gx6NtIMStacS4xLrEvAR0xYDFgsWExYbFiMOMwqDFjBrFj8WRc8KAxZ_FoceKGcWlxafFqcWrxa3HjsamxbXCpcmedMatwq3HhseIx4osxoPGhcawxokBI8a1xrfJn8KRyaHGgca2yKPFrceEyajHiceLx43HjwEkx6HHo8elx6fFvMKBwqjEiWNpbcSzcxLItMSZJMatwqtDcsSqdG8vSMSDaMmFxLvEjkrEjg7Ji8WFwpJ4HsmTYcWSxZTFlsWYYcWaxZzDg8mXxaINyZvEicmdbsa4yaDGvMmiyaTJpsmsxqAsybzHismuxrIIybLJuca5ybbCpMaXc2jHhMuBZ8eMxrHHjsSOBcqDx6THisqGyZXCicSkxJk5xq3Cr0Rpc3DEgnkvQcesxbxzyp_EvAMgFMqlZcS8AVRQyqrKrMWVxZfFmcWbxZ3KtMeKy7PFpsq4xarKusm0ybbCoMatAMuGxI4Ty5nKhceoc8KDwqvGkcaTa8eoU8mMMsKry6dhxLZoxZfFosKgwqXHp3RsxbbLq8W6y63Lnsi1RMatwqrLpMumy6gvUVLLr8ONBVpGy7TLtsKQxI7CkMu6xZPLvMqvyrFkyrPFoMWiFsq3xajMhsq7xrrKvWXMisSpxKvMjMaixI4hx5LHlMevx7HHs8e1x7fHuce7x73Hv8iByIPIhciHyInIi8iNyI_IkciTyJXIl2PMkMubzJLCgsKmcXLMmsWFxI4Yy5RnyKHDgsqRxI7MvM2UZcujy6XMnsupRMu9YXLLrsS5yqAFHsONAljMvcOMwr43zYLJls2Jx4oczYzKuc2PzInMi8yNyoHLic6hzZHNk8aAx4XHh8m9y5TElnPDgM2yx6bMksKEzJXGksaUzJnMm8ydxILMoMyix4rCr2VudMeKIM-DeHQgaMeKxqjMpsyowqfOisqvzo3CpXbEs3Vlw4s_Fg_CljLDuEjDvs6BASXLosqWypjKmktleSBQxphyzLgCEsOMw7DLtMWHMMOKQ1PCmcKaxYzFjsWQyqvNg8quy77FnMWezpxyD86fzY7Jn8KSybbCrVvHomnPlM-DIGvPqcaazoTGncafxqHGscuXybbCqGfPgceKYc-Dxq3Gr8aiw4DOpsmfxbDNkcydxoTQkWXQk8-py5HGnsaFzq5ry5bPosm2x6F1xpFpY9CwedCy0JnQtXPCkMm2x6vMq8W90YHQtMeNwpPMjsaKzZjOssucwoDPoUnGrcKsScyHdC9OzqzHisy4AcKkxL16zpbCvjLOmsyBcsyMzITNjcmkyrzGjc2SzqPQptCoy4vOqMm70Z3JvsuVyoAo0ZHMksyUzJ7OvWzFosKhx5HPjcaB0ZzJqceLz5Rsz5bCozAuMc-hS8qUz6VwypnKm8qdy6_DkcO8Nsy8xYPKpsqozYLKrc6LzYbNiMmYcgzQiNGtybXNkcmj0ZnLgNCzy4LLhHLOpCrRs9GuxqfLjcqd0YrGoNGDyoAr0bzFvNGTy5_Ejk7RlsStxK_EsceAx4LSmcO9w5rSncmMz7XFis-80qHNhNCCzYfRqBHSqdGZxa_RhsW40YjFvtCXy5LOpCzJtsaPzJbGlMaWxphu0JbOqtOizZcBLcm2xqnPisaszoTQpdCbAS7Sts2Q0a_GvtOKxLbRttKI0r3EjjDNmmVsxYjTgHPHqtOex61zzZx4NGYyMTMxOMiRODnIlDY4MGQ1yIvFnDQwYTk2ZceZMDU4yII0YjI0Msiax6PIncWiyKDIosikyKbIqGnIqm_IrMiuyLDIss-hUsi4yLppyLzIvsmAyYJlyYTOj8KSw5HDvsKs04_FhdORyZAxyZLPvsu70IHKsMu_0qXFohfTms6n0a_Srca4yabSssmr0rDQmsmvMNO7ybbCpsm41abQl9Ky1IMBMdSKyojKisqMyo7KkNODAU_MsNGYxrgvVGXPh9KZw7zChgrMvcSOLNGm1ZrQgNKj1Z7RqNGg0avOoMyI0bXOhM2WxrHQp9Wx1pjRr86pxpzLktW1LdSKzrXTp8yYZc25Zcyc0b9lzKHSgc6_z4HPg3LPhdaGz4jPisW7zKVpzKfHg9aFz4fPk8-VZdS4yKNzyKXIp8ipyKvIrcivyLFyyLPVvk3WgdGZ1oTWt9KZw7so1ZTLtdaN1o_JlNKizYXWk9CFAtWi1p_Gp9ahxajLhtadybPRtNag0rvLk8m_xI4q1qbOtsyXzrnFhdatzrzWr86-cs-Az4LPhM-G1rjPi9a71r3CpNa_dNeB0otlwqnKjc-DdXNmZzfPoVPLosyyzogvz5DEgs6N0pnDv3Qo0aTOmdaQ157TltCE0qYa16PXq9el0bHTuDHVrtaZzqrVtMeNzrHIm8yRxbzWp8631qnWq9e3zJ_Xudax17vWs9e-1rfPidiB0oXPj86Lz5LSis-WAM-hUNGW1oLFrcSxxa3KmW7WiMOqw5DCks6Ww4jXnM-_2KLVndCD0agD2KfSt8W116bTt8SW16nLisS7zqLTttW1LtmqxoDCrtWoYm_Fl8iLbtGD2LLKhM2zxbzCg9iHz5bCqGPElMaUIMmi0oXCpkLZkW_ZtsWWdc-CI8-hLdeS1oPYhcuvKMqj1owB1o7TlNWc0qTRqATZodKr16zWmteo2K3aodOt1arVtQjXstao17XWrM672LvWsMWi17zWtNa2z4fZgta60oXYhNa32b3EkNmyd8qGZsaEyKh5z6FV2Y3Xk9qHyKLaic-vwoDEvcOe2ZjZmtWb1pLZntCFBdqf2a7Eq9mla9mnyrvQi9iu25jVtTTbl2XZsNG3LNmy2bTHgdm31IrZvNmIZdm_2oFr2oPPjNa8zKjahtqI2orGts-CCc-hQtuG1oPbiNmSz68czpMI24_amtuS05fQhQbbltuexq7ao9aexa7bndql25_Xr8az26LbpNKI26bZs8yo26nYsdur2rvbr9C927HahNu0xoHcgNqJxqnbuXQfz6FMz6TKl9KVz6fPqc-rz63WiMOW15nPtc-3z7nPu8WN3IfXn8qy0ajKpNaW0InckdCM0I7QrdCi0K_QlHnTrNai1arOpCvQndCfyK5y3YnQpNyP16rTnNCr0I_QrtC_163Rg9GFzZHQutC80L7di92f3JU5053LrNGJ06Hap8eNy7YsxI4y1IrCgMytxJlU2JTOh8y0zKrUjtOMw5B42pfLuNGn0IUS3Izck9en06_ds9iz2brMk9ezzrjWqs661q7asMeKzKTZhN28y63PoVvGrcKw2JXMtNiFQcW7YdOMw4bEjtqe0p7XmgHCuMOMwpXeg9KmEN6G2KndrdCZzqQ52qTesdqm0YLcnt6LzrPKh9iCzKjCqN6f3qHPoUrVhsi7yL3Iv2_JgcmD24vRos-0yY7Vl9WZyZTOm9KmC96wyr7Srs6EyafbpdOu07go3rbFtdWw16rUgc6t3JUp1bjKicar1bvIvNW9yLVI2pHZj9qT1Y_EjsKaxL3Ni96n3bDbkMmV0agH35bRsNqi0bLckNmi377euNGL0bnEjibaqti32qzYutKA2rHYv9a117_attuz2IPYhdq71JDUktSU1JbUmDLUmtSc1J7UoNSiZNSk1KbUqNSq1KzUrtSw1LLPoUHfr9Ga37HJhsqhxI7CuNqX2pnYodOV2Z3cidKm3IXdg9Kq26LWm9mm35_goIPdjt654KCGASLgoInXtN6Q17baruCgjday173goJDZgda54KCTzKjaudeA263XhNS614jUvdeK1YHXjdePyLVi277Zj9yn2ZPfsgQQw40ELtyG4KC22pvLv9ikxaIJ373ZpN2Y2ajckt633JTgoYVE3JfZsdyb2bXbqt67y5zbrNeC3KHagtyk1r3bttuJ27jajHQHz6Fg4KCt15TWh9-yA8KY243goLTfudmc2pzQhdaL4KC805vaoOChuN6I1pzgoYHXptCY4KCFzq_KgEDgoYjej9i54KGM2LzgoI7goY_atNiA2rfcpeChldiG4KGXyKHXhdeH1LzUvtWA14zVg9W-X9OGxK7EsFPPgWQgVHjMuATDts6Tw7jfjs-2QynPutOT1pDfk8WiGNmh0KrRr8aCaWfIrmTXrc6kQdOlxpDYt9Opxpngo6PTr0DLjMWbbuCjotO2zqRE0rbgobfFtdK5y4_dp-ChhULRhsW7xLZp0pXHhG9iasar2Ibeutm53rzUi9GH1I7CoNS0yJzInnLgoZjXhtS714nUv9eL1YLXjs-hYcmm3p1hy6lX0KLGlsy4BcSNA8Ks4KC0PN6txaIb2p_Gu96H4KC_xrLFjsSCx5TCoNO74KSv4KKhANm31IZswqDVuN6-xqjgpKF0xpbPoUfem9OHxLBU3ZVuc8yfx6fbiuCilMKO4KOP4KORz7LFjMOMwrrgpKvHihPZocKZ4KOm1qjgo6nTq-Cjq9ac4KOm3Zzdid2L3Y3Ggd-cya8ly4xbypngpajgoqbGoM6kJtGGW9ut4KWo35rcmeClqsayKdWvW8iodGHgpbDgpbvDgNC5W2fEg0zKjNa84KW41ajgpoTgpobgpohzUMaExLbgpo3fm92P0KbgpbXEh8eC4KaW4KW64KaY4KWjzZHJi-CjoN2X06800rbClMm2wqvGnseB4KWNY-Clj27gpILgpITgpIbdoNWvxYPgo6DFnOCjuuCiqMSO4KOlzZHgo57gprfgo7HGgMO_4Ka04Kahy47LkN6y4KKn0LbCkNSKwojau8OLO8O9woPDiU_CtsOSwq3EnNqJxLbDgMKk4KaAYcKix7HCo-CmkcONWcOY0J7Eg-Cmk9C9ZcOOw7RhCQDgpI_UtseKw5k94KK54KGZyo3EldWBLsSVZnXdleCnucqadsSwZTU5yInIhWPIkTJmNDfWrNSnM2Y1ZsedNs2e1qxmOMqD0JDdic-oecOZQsex1K04NzM3xLYwOGM2N2HHmjE3N2bHvGU21LBm4Kil1KTIl8e01KvIlTTIkdSn4KiXZjEyMOCoice2Y2Q2ZtSZ4KiiZsKiypngoJfUk9SV1JfUmdSb4KmI4KCf1KFh1KPUpdSn1Kk11KvUrTnUr9Sx0abHjcSgG8KWy5fEjiQAxI4lxanLkuCpqAEIxI4t4KmsyoEAwq3LksuD0bfgqbET4KmtAsSOOQAA4KmxGuCpv8Sm4Kmv1argqbEgxI5C4Km2PgLDv-CpsSHgqocBROCqg-CpsSLgprvgqo8B4KWxZ-CpsSPgqojEjkXgqbjgpo7gqorgqargqqPgqbZG4KqY4Kmt4Kmt4Km2R-CqneCpsOCgh8SOSOCqrwLgqp7gqbHalQFJ4Km2SuCqpeCml9CZ4KmxKcqh4KqvA-Clucm91angq4HXsMSOTeCptkvgqbjgqbrSsuCpsSvEjuCrj8SOTOCqieCritqY4KuX4KqAAU7gq5nGheCpsS3Ejk_gqbZO4Kqx4Kqn07nEjlDgq6bgqpHgqbEw04TgqbZS4Kq_4Kae4KuaMcSO4KuzxI5T4KqsATLgq5zEjlTgq7w0xI5V4KqvCOCqkuCqgeCrlwHEjlvgq6DGoOCpsUDEjmDgqbZf4Kuo4KuaQcSO4KqwxI5f4KyO4Kqf4KqN4Kyb4Km2YeCrvETEjmLgrJTgqpHCpmfHo3XFmsKQwqbFlm5m4KOfwoDCp3bHisWD2onPmMOZwpngrLzgrLzCmg"><em>click here to edit this workflow on eth.build</em></a></p>
<p>O bloco <strong>TRANSACTION</strong> é o bloco que vai fazer a transação de moedas, ele recebe 3 parâmetros, <em>privateKey</em>, <em>to</em> e <em>value</em>.</p>
<p>A <em>privateKey</em> é a chave privada do endereço que vai enviar a moeda, o parâmetro <em>to</em> é o endereço que vai receber a moeda, e o parâmetro <em>value</em> é o valor que será enviado. Este bloco retorna a <em>hash</em> de assinatura da transação, o <em>signed</em>.</p>
<p>O bloco <strong>SEND TX</strong> é o bloco que vai executar a transação, ele recebe o parâmetro <em>signed</em> da tramação e o endereços da rede blockchain usada. Ele retorna uma <em>hash</em> de confirmação da transação, que no caso ai não ocorreu por algum motivo, eu acredito que seja porque a rede que estou usando não é minha, é de que vez a playlist de videos que estou acompanhando.</p>
<hr>
<h1>Referências</h1>
<p>Austin Griffith: <a href="https://www.youtube.com/playlist?list=PLJz1HruEnenCXH7KW7wBCEBnBLOVkiqIi">https://www.youtube.com/playlist?list=PLJz1HruEnenCXH7KW7wBCEBnBLOVkiqIi</a></p>
<p>eth-hash: <a href="https://github.com/ethereum/eth-hash">https://github.com/ethereum/eth-hash</a> [<a href="https://github.com/mateusfg7Forks/eth-hash"><em>fork</em></a>]</p>]]></content:encoded>
            <author>contact@mateusf.com (Mateus Felipe Gonçalves)</author>
            <category>blockchain</category>
            <category>hash</category>
            <category>cryptography</category>
            <category>tool</category>
            <category>ethereum</category>
            <enclosure length="0" type="image/png" url="https://mateusf.com/blog/post/learn-with-ethereum/thumbnail"/>
        </item>
    </channel>
</rss>