# data[].attributes.body
Nesse mural você encontrará todas as atividades de preparação para as aulas de Paradigmas de Linguagens de Programação em Python, bem como links para acessar aos desafios preparatórios!

# data[].attributes.attachment_link.readable_text
Aula 1 - Apresentação da Disciplina (P1, P2, P3)

Material

3.29MB

Aula 2 - Paradigmas de Linguagens (P1, P2, P3)

Material

3.64MB

Aula 3 - Trade-offs em Linguagens (P1, P2, P3)

Aula 4 - Nomes e Variáveis (P1, P2, P3)

Aula 5 - Escopo (P1, P2, P3)

Aula 6 - Tipos de Dados Básicos (P1, P2, P3)

Aula 7 - Aglomerados de Dados (P2, P3)

Aula 8 - Tipos Avançados - Parte I (P2, P3)

Aula 9 - Tipos Avançados - Parte II (P2, P3)

Aula 10 - Expressões e Atribuição (P2, P3)

Aula 11 - Subprogramas (P2, P3)

# data[].attributes.attachment_link.title
Prof. Caetano - Paradigmas de Linguagens de Programação em Python

# data[].attributes.attachment_link.description
Paradigmas de Linguagens de Programação em Python

# data[].attributes.body
Vídeo curto apresentando porque todos deveriam aprender a programar (5 minutos).

# data[].attributes.attachment_link.title
Por que todos deveriam aprender a programar? LEGENDADO

# data[].attributes.body
Texto curto apresentando nove razões para aprender programação (10 minutos).

# data[].attributes.attachment_link.readable_text
4 de abril - min de leitura

"Todo mundo deveria aprender a programar um computador porque isso ensina você a pensar". A frase de Steve Jobs sobre programação, que ficou conhecida em 2013 pela campanha da Code.org, resume bem a importância que aprender a programar tem para a sociedade e para o próprio desenvolvimento das pessoas. Não é à toa que instituições como a Code incentivam o ensino da ciência da computação desde a infância. Para diversos especialistas, a programação é a nova alfabetização. Só nessas poucas linhas você já tem explícitos pelo menos dois ótimos motivos para aprender a programar, mesmo que você não queira se tornar um programador. Se você ainda não se convenceu, confira a seguir nove razões para entrar de vez no universo da programação:

1. Faça a diferença no mercado de trabalho hoje e garanta a sua presença nele amanhã

A razão mais óbvia para aprender a linguagem dos computadores é estar preparado para o mercado de trabalho, seja para atuar como programador atendendo a uma demanda crescente por este profissional, com salários que vão de 2 mil a quase 9 mil reais, seja para atuar em outras áreas, segundo o site Love Mondays - uma comunidade online de carreiras. Os softwares já estão em toda parte e a expectativa para um futuro próximo é que a tecnologia esteja ainda mais presente, por meio de chips programáveis, do conceito de internet das coisas (IoT) e inteligência artificial. A digitalização e a robotização devem eliminar várias profissões que existem hoje. Segundo a consultoria Ernst & Young, serão pelo menos 10 até 2025. E mesmo as que permanecerem serão profundamente modificadas, pois todas as áreas farão uso de tecnologia. Ou seja, os profissionais que a dominarem se destacarão. Aliás, eles já se destacam, pois a falta de profissionais capacitados para o digital é uma realidade, como mostra a pesquisa "The Digital Talent Gap – Are Companies Doing Enough?", feita em nove países.

2. Aprender a programar te ajuda a pensar

Assim como Steve Jobs afirmou, para João Vilhete, professor e pesquisador da Unicamp, ensinar programação é o mesmo que ensinar a pensar. Ele se dedica há anos à robótica pedagógica, tendo inserido em escolas ambientes de aprendizagem baseados em dispositivos robóticos que permitem a construção do conhecimento nas diferentes áreas das ciências. Na transição da era da informação para a era do conhecimento, "aprender a aprender" é um diferencial. Com tantas informações disponíveis facilmente e em tempo real, os modelos de aprendizagem pautados na simples transmissão de conhecimento já não fazem mais sentido, especialmente para as gerações que nasceram conectadas. O conhecimento passa a ser construído e saber pensar é o caminho para se tornar um autodidata, o que, com certeza, faz toda a diferença.

3. Programação é a nova alfabetização

Você pode não querer virar um escritor profissional, ainda assim, deve achar essencial aprender a ler e a escrever. Essa deve ser a nova lógica para o aprendizado da linguagem de programação. Por isso, a disciplina tida como uma das habilidades essenciais do século 21 já é vista como a nova alfabetização ou o novo inglês. Segundo Resnick, nesta entrevista publicada no Portal Exame, "em um mundo repleto de tecnologia, quem não aprender a programar será programado". A falta de letramento digital também é preocupante. Para Ali Partrovi, um dos criados do Code.org, é uma questão de sobrevivência, uma necessidade para continuarmos conectados ao mundo. "Tudo o que fazemos responde a um algoritmo. É hora de que todos entendam como e por quê", disse em entrevista ao jornal El País. Ou seja, a programação não é, necessariamente, um fim, mas, com certeza é um meio.

4. Aprenda várias disciplinas ao mesmo tempo

Aprender programação é se desenvolver multidisciplinarmente, já que requer colocar em prática uma série de teorias ensinadas em física, matemática e química, alguns idiomas, como o inglês, além de várias linguagens de programação. Há até quem chame essa forma específica de raciocinar de "pensamento computacional", que atribui os fundamentos da computação nas mais diversas áreas do conhecimento, combinando matemática, lógica e algoritmos, em uma nova forma de pensar sobre o mundo.

5. Desenvolve a habilidade de resolver problemas

O pensamento computacional traz, inclusive, a metodologia para solucionar problemas, que parte da divisão da questão em uma sequência de partes menores. Afinal, não tem como fugir: tomar decisões e resolver problemas são ações quase que obrigatórias em nossas vidas (ainda que não sejam sempre lá muito bem vindas!). E programar é, no fundo, exatamente isso. O processo de aprendizagem tem mais a ver com o processo de superar problemas do que criar algoritmos complicados. Aliás, a própria definição de algoritmos mostra essa relação, já que eles são uma série de instruções que buscam resolver um problema e gerar um resultado. É também a busca por soluções que viabiliza a criação de recursos que facilitam o dia a dia das pessoas, como o DropBox, criado a partir do problema de seu criador, Drew Houston, que sempre esquecia o pendrive.

6. Não é só uma questão de máquinas, nem números, tem a ver com humanidade

É difícil imaginarmos a vida sem uma série de facilidades que a tecnologia nos trouxe. Aprender a programar é ter nas mãos o "poder" de melhorar ou facilitar a vida das pessoas, por meio da criação de softwares e aplicativos que possam resolver problemas reais da sociedade e tornar o mundo um lugar melhor para se viver. "É a coisa mais próxima que existe de ter superpoderes", como citou Houston. Nas palavras de Gabe Newell, criador da Valve, "os programadores são os magos do futuro".

7. Trabalha a persistência e a capacidade de superação

Se a sensação de criar uma solução que pode estar disponível para bilhões de pessoas é a de superpoderes, o processo criativo, por outro lado, não tem nada de mágico. Como qualquer habilidade, são precisos muito treino, dedicação e persistência. Antes de chegar à resolução de cada problema, há uma sequência de erros e tentativas, muito mais presentes até que os acertos.

8. Estimula a criatividade

Para Resnick "programar estimula você a praticar sua criatividade e a desenvolver novas formas de se expressar". É dar vida às ideias, a universos até então inexistentes, a soluções até então impensáveis. Como acreditava Albert Einsten, a imaginação é mais importante que o conhecimento. E a programação é um dos meios possíveis de transformá-la em realidade e fazer a diferença no mundo.

9. Todo mundo é capaz de aprender

Assim como não precisa ser um gênio para aprender a ler e a escrever, também não precisa ser um gênio para aprender a programar. Agora, se você quer ir ainda mais longe nesse universo da programação, conheça os cursos Desenvolvimento Web Full Stack e Desenvolvimento Mobile Android.

#UX

#Marketing

#Carreira

#Tecnologia

#Dados

Vantagens do framework Scrum e seus pilares no gerenciamento de projetos

Ultimamente, muito se fala sobre empresas que precisam se adaptar à Transformação Digital e como as metodologias e ferramentas podem ajudar nessa missão. As vantagens do framework Scrum se destacam tanto, que fica impossível não dar espaço para esta metodologia ágil que alcança a liderança.Fazendo uma rápida retrospectiva, o Scrum nasceu com o objetivo de simplificar e garantir as entregas de projetos, inicialmente para a área de Tecnologia da Informação(TI) e desenvolvimento de software. Mas, com o passar dos anos, as empresas passaram a enxergar valor em todas as entregas, dentro de prazos previamente acordados. E aí, o Scrum cresceu, com sua popularidade justificada por conta de alguns benefícios importantes. Vantagens do framework ScrumAbaixo, nossa professora, líder dos cursos executivos e Scrum Master, Aline Przybelak, elenca alguns benefícios que mostram por quê Scrum é importante no universo dos negócios.1 - AdaptabilidadeEnquanto os métodos tradicionais de desenvolvimento, em especial o cascata, valorizam análise extensa e definições rígidas de requisitos, visando "segurança" (ou a falsa sensação dela), o Scrum abraça a imprevisibilidade que um projeto longo possui ao inserir mais resiliência a ele.Esse é um dos pilares da ferramenta Scrum! Como diria a equipe dev do Spotify, construa princípios sólidos e metas claras, mas adapte a execução conforme a necessidade. Isso é ser ágil.2 - TransparênciaScrum fala de adaptação, mas não há como se adaptar ao que não se consegue ver. E é por isso que o primeiro pilar da metodologia é a transparência. Tudo começa com ela.Sem transparência não há:➜ Inspeção adequada;➜ Adaptação;➜ Engajamento;➜ Confiança;➜ Evolução do time;➜ Sucesso no projeto.Precisamos promover a transparência em todas as áreas e todos os níveis da empresa. Geralmente, há receio em mostrar aos times o andamento dos processos e projetos, a fim de "proteger" o time de problemas. Mas, John Maxwell diz que "não tem como o time saber se está ganhando se ele não pode ver o placar!". Quanto ao time, todos os envolvidos têm uma visão ampla e transparente de tudo o que diz respeito aos projetos. Portanto, é muito mais fácil conseguir se adaptar às mudanças e entender para onde a equipe deve ir.Tem um ditado que diz o seguinte: se você não sabe para onde está indo, qualquer lugar serve. Um projeto não fracassa, se não havia um objetivo para o mesmo, certo?!3 - Feedback contínuoO Scrum na prática fornece diversos mecanismos de feedback, o que garante o segundo pilar do framework: a inspeção.Feedback contínuo não é dar tapinhas nas costas na reunião de final de ano da empresa. Tem a ver com transparência, pois o time precisa saber se suas ações estão gerando resultado. Afinal, você precisa saber se está no caminho certo.O feedback precisa ser desmistificado dentro das empresas, ele não é só para falar as coisas boas ou apontar os erros. O feedback tem muito mais valor quando é construtivo, alertando o indivíduo em pontos de melhoria.Inspeção leva à adaptação, ou seja, um ciclo virtuoso que gera a melhoria contínua.4 - Melhoria contínuaNesse processo, as melhorias ocorrem Sprint a Sprint. A cada novo ciclo, geramos um novo incremento e ajustamos o que não ficou tão bom. É assim que o Scrum no dia a dia faz a diferença.Por isso, conseguimos gerar valor ao produto, pois estamos sempre ajustando e melhorando.Na metodologia de inovação em startups denominada Lean Startup, existe um ciclo chamado construir-medir-aprender (build-measure-learn no original), que trabalha da seguinte maneira:1. Você constrói um incremento de produto;2. Mede o desempenho dele;3. Aprende com os erros e refina-o;4. Volta ao passo 1;5. Entrega contínua de valor.Com o framework Scrum, estamos sempre entregando algo ao nosso cliente. Mas, é importante salientar que não basta apenas entregar algo, ele precisa ser realmente de valor.De nada adianta entregar um aplicativo com tela bonita e inovadora, por exemplo, se ele não funcionar.Se não está tão bom agora, certamente na próxima sprint ela será melhorada (melhoria contínua). Você nunca terá como entregar tudo o que o cliente quer, no prazo que ele quer e dentro do orçamento dele. Isso não existe. Mas, o processo de criar e priorizar um Backlog de Produto garante que as exigências de maior valor ao cliente sejam atendidas primeiramente e que o valor que ele tanto busca (não confundir valor com custo) seja entregue em partes, à cada iteração.5 - MotivaçãoE no método Scrum, como devem ser as reuniões diárias? Os processos de conduzir este encontro e de Retrospectiva da Sprint conduzem a níveis mais altos de motivação entre os colaboradores.Uma das chaves para a motivação é o que Simon Sinek chama de Golden Circle, neste brilhante vídeo. Conforme evidenciado, não apenas nesse trabalho (do vídeo) mas em muitos outros, é necessário um ambiente de alta confiança para que o time se sinta motivado a seguir em frente, em prol dos objetivos gerais da sprint.Todos os passos anteriores geram motivação ao time, que precisa ter tranquilidade para trabalhar em um lugar seguro e ter as informações que precisa para saber pra onde ir, com feedback constante que garanta o engajamento, apontamentos de melhoria etc. Se o time for encorajado, certamente estará motivado em fazer as melhores entregas.Quer saber mais sobre metodologias ágeis e as diversas habilidades digitais que permeiam a Era de transformações que vivemos? Então, acompanhe este blog diariamente. Aqui, desmistificamos este universo e ainda convidamos você a fazer parte dele conhecendo a grade de cursos da Digital House.

#Marketing

E-commerce na prática: como montar uma loja virtual do zero

Desde que a pandemia causada pelo novo coronavírus chegou ao Brasil, o comportamento de consumo das pessoas passou por mudanças significativas, o que também mudou a atuação de varejistas e muitos começaram um e-commerce do zero.Neste cenário, o virtual ganhou uma importância nunca antes vista no país. Segundo estudo do Movimento Compre&Confie, em parceria com a Associação Brasileira de Comércio Eletrônico (ABComm), somente nos cinco primeiros meses de 2020, o e-commerce brasileiro faturou quase R$ 42 bilhões, número 57% maior do que no mesmo período de 2019.Nestes números, estão inclusas 100 mil novas lojas virtuais que foram colocadas no ar durante a pandemia. Fatores que já seduziam empresários, como baixo investimento inicial e boa rentabilidade, ajudaram tanto quem já pensava em abrir um e-commerce quanto quem precisou fazer isso às pressas.Com isso, vem também a necessidade de alertar sobre a importância de se ter organização e planejamento na hora de abrir um e-commerce do zero. Afinal de contas, seguindo uma tendência geral do empreendedorismo no Brasil, muitas lojas virtuais 'fecham as portas' ainda no primeiro ano de atuação.PlanejamentoO primeiro passo é estudar o mercado digital e saber mais sobre o segmento no qual se pretende ingressar. Com isso, é possível conhecer e entender as 'dores' dos consumidores que serão o público-alvo do negócio, para saber como os produtos ou serviços que serão oferecidos podem saná-las e agregar valor.Pensar no real propósito do negócio é, mais do que nunca, um ponto fundamental. É preciso saber onde se quer chegar. Consumidores são ainda mais exigentes nos meios digitais, e estão cada vez menos dispostos a comprar produtos e serviços que não agregam valor e não entregam um propósito muito claro.Estabelecer metas iniciais pode ajudar a mensurar o andamento do negócio em seus primeiros passos, principalmente quando se fala em estruturação do modelo. Por isso, é importante, também, conhecer a concorrência do segmento, pois ela pode ter muito a ensinar, principalmente com problemas enfrentados anteriormente.Avalie os diferenciais que o negócio pode ter. Oferecer mais do mesmo, definitivamente, não é o melhor caminho.FornecedoresTão importante quanto saber o que e para quem se quer vender, é saber de quem se pretende comprar. Pois é, quando você abre um e-commerce do zero, logo percebe que precisa de fornecedores, pois não há como focar no core business ao mesmo tempo que se tenta fazer tudo o que é necessário para ter a loja no ar.Pense que, para os produtos, você precisará de fabricantes, distribuidores, etc. Para o funcionamento da loja (site), você precisará de uma plataforma, dos meios de pagamento, de um sistema antifraude, dos canais de venda, etc.Parece muita coisa, mas não se assuste. O mercado tem diversas opções muito interessantes para quem está começando um e-commerce do zero. O nível de investimento não precisa ser alto para quem não vai nascer gigante, como é o caso da maioria das lojas virtuais que surgem.PlataformaPara a escolha da plataforma, é preciso considerar o quanto se pretende crescer em curto prazo, pois só assim será possível definir o tipo ideal para o negócio. O mercado oferece algumas delas gratuitamente, com código aberto, mas somente as pretensões do negócio, somadas à disponibilidade de investimento inicial, poderão clarear a escolha.Quando buscar fornecedores de plataforma, lembre-se de perguntar sobre a estrutura do código-fonte. A maneira como o código-fonte de um site é estruturado tem se provado, repetidas vezes, um importante fator de ranqueamento na página de resultados do Google. Plataformas de e-commerce que optam por um código limpo, de fácil compreensão e fortemente baseado em HTML tendem a ter vantagem nessa questão.Além disso, pense no tempo de carregamento da página e tenha em mente que é importante considerar o que foi estudado no momento do planejamento. Por exemplo, não adianta criar um site que não seja responsivo a smartphones, pois o crescimento das compras via celular têm aumentando ano a ano.LogísticaParte vital de um e-commerce, a logística tem que ser muito eficiente. Ela é a responsável por praticamente todas as etapas do fluxo de validação e finalização de uma compra.Aqui, o varejista pode optar por trabalhar com os Correios ou transportadoras particulares. Independente da escolha, não se pode perder de vista a preparação para uma logística reversa, pois produtos, em diversas circunstâncias, podem ser devolvidos ou trocados por clientes, e este processo não pode ser um problema.Meios de pagamentoOs meios de pagamento são as ferramentas responsáveis pelo caminho que o dinheiro percorrá da conta do cliente até a do varejista, e é fundamental que o comerciante conheça cada etapa deste processo.No e-commerce, quando se fala de meios de pagamento, não se fala apenas de dinheiro, cartão e boleto. Atores como emissor, gateway, adquirente e subadquirente, pouco conhecidos por quem não atua no setor, são primordiais para que lojistas virtuais não percam vendas no momento do pagamento.Cada lojista deve levantar os pontos que considera mais importantes para tomar a decisão sobre qual dos meios de pagamento deve utilizar.É preciso considerar qual é o melhor sistema de cobrança para o modelo de negócio, comparar taxas cobradas por transação e emissão de boletos, escolher adquirente, gateway de pagamento, quantidade de bandeiras aceitas, solução <strong>antifraude</strong> utilizada, etc.AntifraudeO aumento significativo das vendas no e-commerce aumenta também a fraude no setor. Segundo estudo da ClearSale, entre 1º de janeiro e 31 de maio deste ano, mais de R$ 608 milhões em fraudes foram evitadas.Considerando que o comércio eletrônico não dispõe de alguns fatores de segurança que são comuns ao varejo físico, como presença da pessoa e checagem do chip do cartão, por exemplo, é importante contar com uma solução antifraude que ofereça equilíbrio entre tecnologia e inteligência humana para desenvolver camadas de segurança.A ClearSale, por exemplo, investe maciçamente em inovação e tecnologia, o que permite aprovar, em média, 97% das compras de e-commerce, número substancialmente superior ao de países do primeiro mundo.Isso quer dizer, entre outras coisas, ao pensar na escolha dos meios de pagamento, o varejista precisa ter em mente que o uso da solução antifraude pode não apenas garantir a segurança, mas também ajudar a aumentar suas vendas.Estrutura e modelo de negócioOs pontos anteriores dizem respeito ao que é necessário para colocar uma loja virtual no ar, mas é preciso pensar, também, em tudo o que é necessário para que haja tráfego (audiência) e que funcione. Ou seja, para que seja possível receber pedidos e finalizar pagamentos.Além da estrutura legal, para que seja uma empresa devidamente registrada e regulamentada, é neste momento que o empreendedor precisa ter foco em ações que trazem o máximo de resultado, investindo apenas no que é realmente necessário para o que se chama de 'mínimo viável'. Isso significa focar em pontos sem os quais não é possível colocar a loja para funcionar, e deixar todos os outros para um segundo momento.Canais de tráfego no siteVia de regra, para iniciar a estrutura de vendas em um e-commerce, não é preciso muito mais do que um meio para atrair audiência e um outro para concluir as transações. No que diz respeito à audiência, as redes sociais podem ser grandes aliadas de quem está começando um e-commerce do zero. Elas são capazes de ajudar na captação, no atendimento e na fidelização de clientes, os quais passarão a conhecer o que você oferece.Ainda no sentido de trazer mais audiência à loja virtual, vale ressaltar que campanhas afiadas de marketing digital podem colaborar substancialmente com o aumento de tráfego qualificado e, consequentemente, trazer mais conversões para o e-commerce.Canais de vendasO canal de vendas mais óbvio é o da plataforma. No entanto, a plataforma, por mais acessível que seja, traz consigo a necessidade de outros fornecedores, como visto anteriormente neste artigo, o que pode não ser o mais interessante para todos que estão ingressando no e-commerce. Alguns iniciantes podem optar por tentar vender antes mesmo de colocar o site no ar, até para testar se há ali realmente uma boa oportunidade. Para isso, algumas alternativas que têm sido bastante utilizadas são os marketplaces (como o Mercado Livre, por exemplo) e os links de pagamento, que podem ser enviados por WhatsApp ou redes sociais.Dessa forma, enquanto você estrutura e testa alguma opções para seu e-commerce, produtos ou serviços já podem começar a ser vendidos. Assim, quando a loja virtual entrar no ar, você já terá algumas lições e sinais importantes sobre o que funciona e o que não funciona para sua loja.Atendimento ao clienteA excelência no atendimento é o que traz ao cliente a segurança de que eventuais problemas serão sanados sem qualquer transtorno, além de ser um ponto que garanta à empresa que seus clientes farão o melhor uso de produtos ou serviços.Segundo uma publicação da revista Harvard Business Review, 23% dos consumidores que tiveram experiências boas com o atendimento contaram dessas experiência a 10 ou mais pessoas. Já no caso de experiências ruins, o número dobra: 46% deles relatam esse tipo de situação.Ou seja, um atendimento ruim reverbera muito, e a credibilidade ferida é uma das piores coisas que pode acontecer para um e-commerce, principalmente para os que ainda estão começando. Portanto, pense em um atendimento excelente, que possa receber contato do cliente em mais de um canal. Seja rápido e eficiente na resposta, tenha o atendimento como uma oportunidade de fidelização, e não apenas como um problema para o negócio.IndicadoresMuitos são os indicadores passíveis de medição em uma loja virtual. O problema, no entanto, é que muitos empresários não conhecem os números mais indicados para saber se o negócio segue, ou não, em um caminho de sucesso.Taxa de aprovação de pedidosA taxa de aprovação de pedidos é uma métrica primordial, mas que precisa estar em equilíbrio com outros números, como tempo de resposta e taxa de chargeback (estorno).Se a aprovação é muito baixa, provavelmente a taxa de chargeback e o tempo de resposta estarão controlados, mas a loja estará, certamente, recusando muitos clientes legítimos. Por outro lado, se a aprovação é muito alta, mas o tempo de resposta é ruim e a taxa de chargeback também é alta, de nada adianta aumentar o volume de aprovações.Taxa de reprovação e falsos-positivosBarrar fraudes, pura e simplesmente, é fácil. Bastaria reprovar todos os pedidos com traços minimamente fora de um determinado padrão. Alguns fornecedores atuais do mercado, inclusive, cometem este erro.Não são raras as vezes em que um varejista tem de lidar com clientes legítimos entrando em contato para reclamar a reprovação de um pedido. Pensando em tempos nos quais as redes sociais deram voz ativa a todas as pessoas, imagine o tamanho de prejuízo de reputação que tal fato pode gerar.Muitos comerciantes estão fixados em evitar os prejuízos de aprovação de pedidos fraudulentos. No entanto, as estatísticas mostram que os custos da reprovação de bons pedidos podem ser maiores. As perdas por falsos-positivos totalizam cerca de US$ 118 bilhões por ano no e-commerce mundial, o que é 13 vezes maior do que os prejuízos com fraudes em cartões de crédito.Tempo de respostaO tempo médio de resposta de cada transação é um indicador valioso. O consumidor digital é cada vez mais ansioso, e dados de consultorias mostram que 53% das pessoas tendem a desistir de transações quando a resposta não é imediata. Agora, imagine em seu e-commerce quantos clientes podem, por exemplo, abandonar os carrinhos de compra no momento do checkout porque sua análise antifraude é relativamente demorada. Analisar pedido a pedido, de maneira quase que manual, é inviável para quem pretende escalar o negócio e obter sucesso. Procure fornecedores que prezam, entre outras coisas, pela rapidez na respostaChargebackChargeback é o nome dado ao estorno que acontece quando o titular de um cartão não reconhece uma compra. O problema é que, dependendo da plataforma que se usa, é possível que o varejista nem sequer conheça a taxa de chargeback de sua empresa - ou então ele até conhece o número, mas não sabe se é uma taxa alta ou baixa, aceitável ou preocupante.Conhecer a taxa de chargeback, bem como saber se ela está dentro da média de seu nicho de mercado, é primordial para o desenvolvimento sustentável de todo e qualquer negócio.

#Dados

Deep learning: entenda como funciona o aprendizado de máquina através de exemplos

Antes de explicar o que é Deep Learning, vamos contextualizar em que terreno estamos pisando, quando falamos desta tecnologia.De um lado, muita gente acredita que a Inteligência Artificial(IA) nunca será totalmente autônoma, já que a humana estará sempre pronta para burlar seus padrões. De outro, existe o time do pé atrás em relação ao crescimento acelerado dessa tecnologia no cotidiano sair do controle humano. E é nesse fogo cruzado de opiniões que Deep Learning continua a evoluir. Nesse artigo, vamos falar sobre o que é, sua ligação com Machine Learning e alguns exemplos de sua aplicação. O que é Deep Learning - orientada à evolução IA facilita a rotina social, melhora o desempenho dos negócios, possibilita inovações na saúde, indústria e comércio e não para de evoluir. Para que isso seja possível, redes neurais, alinhadas com Machine Learning ou ML(capacidade de uma máquina aprender e aperfeiçoar seus padrões com base em muitos dados), são complementadas, dando base à Deep Learning.As redes neurais são modelos computacionais inspirados no sistema nervoso central de um ser humano. Eles são capazes de realizar o aprendizado de máquina e reconhecimento de padrões. Assim, Deep Learning, por meio dessas redes neurais, é definido como uma categoria de inteligência artificial que complementa Machine Learning, de uma forma mais profunda, como o próprio nome sugere, com o objetivo principal de melhorar a vida das pessoas.Exemplos de aplicação de Deep LearningEntre suas aplicações mais comuns, podemos citar o reconhecimento de fala e facial. Com ampla visão computacional, essa tecnologia detecta e decifra imagens e processamento de linguagem natural, como já ocorre na identificação de rostos para o reconhecimento via smartphones e sistemas de segurança.Age também na identificação de traços que indiquem doenças como câncer e tumores em exames de imagem. Além disso, pode prever falhas em equipamentos, detectar fraudes etc. Deep Learning é a base da tecnologia que rege o Google Tradutor. Além disso, lá atrás, ela foi usada para o desenvolvimento de carros automáticos.Está presente em muitos setores, desde sua incorporação em meados da segunda metade do século 20. Desde então, vêm se tornando cada vez mais presente e fundamental na vida das pessoas, por conta de sua versatilidade e precisão. Por esta razão, o universo dos negócios enxerga Deep Learning como uma ferramenta incrível de crescimento. Seu uso vai de setores como saúde, educação, e-commerce, cibersegurança, turismo, entretenimento e muitos outros. Usando métodos baseados nessa tecnologia, engenheiros, desenvolvedores e cientistas de dados conseguem excelentes resultados em diferentes aplicações, se aproximando cada vez mais da satisfação, preferências e gostos do seu público.E depois do Deep, o que virá?Como dissemos, IA parece não ter muitos limites quando se trata de evolução. Por este motivo, especialistas sugerem que dentro de alguns anos, o relacionamento entre humano e máquinas poderá superar a interação entre as pessoas.Este momento pode não ser exatamente de "substituição", mas uma escolha. Fato é, que esta profundidade toda remete diretamente às carreiras do futuro.Se após ler este artigo, novas interrogações surgiram, calma, a Digital House pode te ajudar a compreender estas mudanças. Além de conteúdos diários no blog, publicamos inúmeros conteúdos entre webinars e podcasts que desmistificam termos e conceitos da Era Digital. Aliás, você consegue acessar tudo na nossa Biblioteca de Conteúdo. Vamos conversar sobre tansformação digital? :)

# data[].attributes.attachment_link.description
4 de abril - min de leitura "Todo mundo deveria aprender a programar um computador porque isso ensina você a pensar". A frase de Steve Jobs sobre programação, que ficou conhecida em 2013 pela campanha da Code.org, resume bem a importância que aprender a programar tem para a sociedade e para o próprio desenvolvimento das pessoas.

# data[].attributes.body
Vídeo médio apresentando três dicas que se pode seguir para aprender a programar qualquer coisa! (15 minutos)

# data[].attributes.attachment_link.title
3 Técnicas Que Eu Uso Para Aprender a Programar Qualquer Coisa (mesmo sem ter o dom da programação)

# data[].attributes.body
Vídeo médio discutindo como escolher a melhor linguagem para começar a programar. (9 minutos)

# data[].attributes.attachment_link.title
MINHA OPINIÃO: Qual a melhor linguagem para começar a programar?

# data[].attributes.body
Para quem prefere texto, um texto curto sobre a escolha da primeira linguagem... outra opinião! (10 minutos)

# data[].attributes.attachment_link.readable_text
Acontece sempre comigo; pessoas que querem aprender a programar me perguntando "onde estudar online", "qual linguagem escolher", "por qual linguagem começar"... e por ai vai. Apresentei a palestra "Como aprender a programar" em alguns eventos, incluindo na Campus Party, e compartilho com vocês aqui parte do conteúdo.

Ha! Veja também minhas dicas e links em Aprender programação online, sozinho e do zero.

Apresentação

Vale a pena saber programar?

O que faz um programador?

Faz códigos. "Código" não tem nada a ver com " senha". Quando se escreve um programa, se escreve código, ou seja, linhas e mais linhas de instrução que fazem o computador entender o que você deseja. Claro que um desenvolvedor faz outras coisas... muitas vezes faz a análise do problema, desenha modelos, mas no final sempre precisa transcrever tudo em código.

Muita gente nunca viu um código, não sabe como é. Separei algumas imagens aleatórias de pequenos trechos de códigos meus pra você olhar. O importante aqui é você pensar se quando vê, acha "feio" e não te chama a atenção, ou se te deixa curioso, se te atrai a entender mais o que é, o que faz e para que serve.

Mercado de trabalho para desenvolvedores

O que você acha? Conhece desenvolvedores desempregados? Já ouviu falar de crise na área de tecnologia?

"Segundo o IDC, o Brasil já é o 4º maior centro de TI do mundo, ficando atrás apenas de Estados Unidos, China e Japão. É o segmento brasileiro que mais cresce."

"Estudo realizado pela consultoria IDC, encomendado pela Cisco, aponta que a demanda por profissionais de tecnologia da informação e comunicação (TIC) no Brasil excederá a oferta em 32% no ano de 2015, chegando a uma lacuna de 117.200 trabalhadores especializados em redes e conectividade. O déficit de pessoal na área de Tecnologia da Informação (TI) é de cerca de 40 mil profissionais de acordo com a Associação Brasileira de Empresas de Tecnologia da Informação e Comunicação (Brasscom)."

"Os cargos que apresentam a maior demanda são: Analista de Sistemas, de Programação, de Suporte Técnico, de Processos, Técnico de Telecomunicações, Analista de Rede, Gerente de Projetos, Administrador de Redes, Webmaster e Técnico de Hardware."

[form_lead form=hangout]

O desafio e a recompensa

Mas, qual a recompensa?

É ter o usuário utilizando seu software e sentindo que é a melhor coisa que existe! É ver que ele resolveu um problema, e que as pessoas realmente gostam da maneira como você fez. Pra mim é isso.

Ambientes: desktop, mobile, web, cloud...

Observe os quatro ambientes da esquerda (A,B,C e D). Agora imagine o que se usa em cada ambiente (1,2,3 e 4).

Quando falamos em desenvolvimento de software, podemos desenvolver para uma grama muito grande de ambientes, que vão desde smartphones (iOS, Android, Windows Phone), desktops (Windows, Linux, Mac OS), web, até aparelhos como SmarTVs, carros, equipamentos de telecomunicação e satélites.

Portanto, é importante entender que cada linguagem atende um ou mais ambientes. Com base no ambiente para o qual você deseja produzir seu software, irá buscar as linguagens adequadas.

Então, não passe daqui se definir um ambiente para o qual deseja programa.... Já definiu?

Linguagens de programação atuais

Existem dezenas de linguagens de programação. Algumas ultrapassadas, outras antigas mas que nunca morrerão e outras modernas e focadas em alto desempenho e performance. Apresento aqui uma imagem para você ver os "nomes" das linguagens mais populares em 2015. Ignore por agora como foi medida a "popularidade".

Mas, qual linguagem escolher para aprender afinal?

Como escolher a linguagem??

Traduzi o infográfico abaixo que irá lhe conduzir às melhores possibilidades. " Qual linguagem de programação aprender primeiro? ", confira!

E então? Achou sua linguagem??? Qual é? Comente ai!

Cursos e certificações

Na área de Tecnologia da Informação, certificações podem ser mais importantes que a própria graduação. A Certificação é a maneira da empresa que cria uma tecnologia atestar que você tem conhecimentos suficientes para trabalhar com ela. Poucos profissionais são certificados se comparando com a quantidade de graduados e pós-graduados.

Quando você se certifica, consegue uma " aprovação " de capacidade que poucos desenvolvedores possuem, ou se dedicam a possuir.

Praticamente para todas tecnologias atuais existem alguma forma de certificação. Os valores podem partir de R$100,00 até R$1.000,00 para fazer a prova. Se não passou, não é certificado. Se passou, ganha o direito de dizer que é certificado e claro, recebe um certificado "impresso".

Como aprender online?

Escrevi um post recentemente com todas as dicas e links pra Aprender programação online, sozinho e do zero! Confira!

Aprender programação em 20 horas

Em 2016 dediquei um bom tempo elaborando essa metodologia, onde o objetivo é ensinar programação para um leigo, começando do zero, em apenas 20 horas. Criei uma turma "beta" que está cursando agora e estão conseguindo realmente aprender. Está sendo eficiente e eficaz.

Parto do principio que aprender programação deve ser divertido, que a matemática não deve ser obrigatória, e que não dá pra falar em termos técnicos com alguém que ainda está aprendendo a técnica. Então o formato é informal e com muita explicação por analogia.

Se quiser saber mais vá até Aprender Programação em 20 horas.

Agora é com você!

Chega de conversa! Compre um livro, veja uns videos, leia na internet, prepare seu ambiente de desenvolvimento e meta mão na massa! Não deixe para depois e também não desista tão rápido. Começar não é fácil, mas sinta-se a vontade para me perguntar e comente aqui sua evolução.

# data[].attributes.attachment_link.description
Acontece sempre comigo; pessoas que querem aprender a programar me perguntando "onde estudar online", "qual linguagem escolher", "por qual linguagem começar"... e por ai vai. Apresentei a palestra "Como aprender a programar" em alguns eventos, incluindo na Campus Party, e compartilho com vocês aqui parte do conteúdo. Ha!

# data[].attributes.body
Vídeo médio apresentando o que são Paradigmas de Programação. (7 minutos)

# data[].attributes.body
Para quem prefere texto... um artigo médio apresentando quais são os paradigmas de programação. (15 minutos)

# data[].attributes.attachment_link.readable_text
Os paradigmas de programação são, antes de tudo, um meio de qualificar a linguagem com base em sua funcionalidade. São atributos que expressam como uma linguagem funciona e também soluciona problemas.
Os paradigmas são classificados de acordo com as permissões sobre o que uma linguagem pode ou não fazer, mas não se preocupe, veremos isso mais abaixo.

Existem inúmeros outros paradigmas de programação, mas neste artigo vamos focar no que é mais relevante de acordo com o mercado de trabalho.
>> Melhores linguagens de programação para devs iniciantes
O que é um paradigma de programação

Um paradigma é um estilo de programação, um modelo, uma metodologia. Não se trata de uma linguagem, mas a forma como você soluciona problemas usando uma determinada linguagem de programação.

Existem muitas linguagens de programação conhecidas, mas todas elas precisam seguir algumas regras quando implementadas. E essas regras são os paradigmas.

Desta forma, quando uma nova linguagem de programação é desenvolvida, conforme suas pecualiaridades, ela tende a se enquadrar em um paradigma ou até mesmo multiparadigma, como o JavaScript, por exemplo.

Conseguiu entender bem até aqui? Pode parecer um pouco complicado para quem está no começo da jornada como desenvolvedor e se este for o seu caso, recomendo assistir ao vídeo a seguir antes de continuar:

Por que é importante aprender sobre paradigmas de programação?

O primeiro ponto é que isso transforma você num desenvolvedor melhor, entendendo melhor sobre este tipo de teoria faz você pensar diretamente no design de código, você consegue ser capaz de entender melhor as linguagens, lendo nas entrelinhas dós códigos.

Outro ponto relevante é que adiciona uma vantagem competitiva para o seu perfil numa seletiva de emprego. Quando recrutadores ouvem que você domina o assunto, isso agrega ainda mais valor ao seu nome durante o processo gerando mais confiança na sua contratação.
>> Dicas de carreira: como criar seu perfil profissional com foco na área tech
Quais são os tipos de paradigmas?

Os principais paradigmas de programação basicamente pertencem a dois grupos, imperativos ou declarativos.
Imperativo

Paradigmas de Programação Imperativos

O programador instrui a máquina sobre como devem ser computados os processos. Dentro dos paradigmas de programação do tipo imperativo temos:

Programação Procedural

A programação procedural é excelente para programação de uso geral e consiste numa lista de instruções para informar ao computador o que fazer passo a passo.

A maioria das linguagens de programação ensinadas na faculdade são procedurais, exemplos:

Quando é recomendado usar programação procedural:

Quando existir uma operação complexa que inclui dependências entre operações e quando há necessidade de visibilidade clara dos diferentes estados do aplicativo.

O programa é muito único e poucos elementos foram compartilhados.

O programa é estático e não se espera que mude muito ao longo do tempo.

Espera-se que nenhum ou apenas alguns recursos sejam adicionados ao projeto ao longo do tempo.

Recomendo a fonte original de onde eu tirei essa informação sobre as recomendações de quando usar programação procedural, incluindo as desvantagens deste paradigma.

Programação Orientada ao Objeto

A programação orientada ao objeto (OOP) é o paradigma de programação mais popular devido aos seus benefícios, como a modularidade do código e a capacidade de associar diretamente problemas reais em termos de código.

Neste caso, o programa é escrito como uma coleção de classes e objetos para uma boa comunicação. A entidade menor e básica é objeto e todo tipo de cálculo é realizado apenas nos objetos.

É o paradigma mais popular e requisitado pelas empresas e as principais linguagens que o implementam são:

Vale a pena utilizá-la quando:

Vários programadores atuam juntos e não precisam entender tudo sobre cada componente.

Existe muito código a ser compartilhado e reutilizado.

São previstas muitas mudanças no projeto.

Computação Paralela

O paradigma de computação paralela consiste nas instruções sendo divididas entre vários processadores.

Um sistema de computação paralela permite que muitos processadores executem um programa em menos tempo, dividindo-os.

Linguagens que suportam a abordagem de processamento paralelo:

A abordagem de computação paralela geralmente é recomendada quando:

Você tem um sistema que possui mais de uma CPU ou processadores multinúcleo.

É preciso resolver problemas computacionais que podem levar até dias para serem resolvidos.

Se trabalha com simulação computacional, inteligência artificial ou modelagem que exija muitos cálculos dinâmicos.

Declarativo

Paradigmas de Programação Declarativos

É quando o programador apenas declara as propriedades do resultado desejado, mas não informa a máquina sobre como devem ser feitos os cálculos relacionados. No grupo dos paradigmas de programação declarativos estão:

Paradigma de Lógica de Programação

O paradigma da programação com apontamento lógico não é composto de instruções. Ele é baseado em fatos e usa tudo o que sabe para criar um cenário onde todos esses fatos e cláusulas são verdadeiros e apontam para algum final.

Por exemplo, JavaScript é uma linguagem de programação, todas as linguagens de programação são importantes e, por dedução lógica, JavaScript é importante.
>> Linguagem JavaScript: Um guia para iniciantes
Linguagens com propriedades de lógica:

É interessante usar o paradigma de programação lógica quando:

Você planeja trabalhar em projetos como prova de teoremas, sistemas de redução, sistemas de tipos entre outros.

Programação Funcional

O paradigma de programação funcional tem suas raízes na matemática e é independente da linguagem.

A base desse paradigma é a execução de uma série de funções matemáticas. Você compõe seu programa de funções curtas. Todo o código está dentro de uma função. Todas as variáveis têm escopo definido para a função.

No paradigma de programação funcional, as funções não modificam nenhum valor fora do escopo dessa função e as próprias funções não são afetadas por nenhum valor fora do escopo.

Falamos bastante do paradigma de programação funcional nesta GeekStream, inclusive é uma das coisas que o Gabriel Schade, da AWS, gostaria de ter aprendido no começo de sua carreira.

Linguagens que usam este paradigma:

Ideal para usar quando:

Tem matemática envolvida diratemante na programação.

Os paradigmas de programação ajudam a reduzir a complexidade dos programas. Todo desenvolvedor deveria seguir uma abordagem de paradigma ao implementar seu código.

Vale pegar seus prós e contras, colocar numa balança e verificar qual é o ideal para o seu projeto.

Você sentiu falta de algum paradigma importante que não foi citado no texto? Deixe sua opinião e nos diga quais você tem utilizado.

# data[].attributes.attachment_link.title
O que é e quais são os paradigmas de programação? | GeekHunter Blog

# data[].attributes.attachment_link.description
Os paradigmas de programação são, antes de tudo, um meio de qualificar a linguagem com base em sua funcionalidade. São atributos que expressam como uma linguagem funciona e também soluciona problemas. Os paradigmas são classificados de acordo com as permissões sobre o que uma linguagem pode ou não fazer, mas não se preocupe, veremos isso mais abaixo.

# data[].attributes.body
Após estudar os conteúdos desta aula, responda ao desafio da Atividade Autônoma Aura! (Formulário disponível exclusivamente de 15/02 a 24/02/2022).

# data[].attributes.body
O que é um paradigma? Vídeo curto em inglês (clique na engrenagem e ligue a auto-tradução para português). (2 minutos)

# data[].attributes.body
Programando Através dos Paradigmas. Palestra (50 minutos) sobre paradigmas no evento GOTO 2017. (ligue a legenda e, depois, clique na engrenagem e ligue a auto-tradução para português).

# data[].attributes.attachment_link.title
GOTO 2017 • Programming Across Paradigms • Anjana Vakil

# data[].attributes.body
O Poder do Paradigma. Palestra (1 hora) do criador do JSON sobre paradigmas. (ligue a legenda e, depois, clique na engrenagem e ligue a auto-tradução para português).

# data[].attributes.attachment_link.title
The Power of the Paradigm. Douglas Crockford. JS Fest 2018

# data[].attributes.body
Vídeo curto sobre a escolha da linguagem de programação para o seu projeto! (5 minutos)

# data[].attributes.attachment_link.title
Qual linguagem de programação utilizar em meu projeto?

# data[].attributes.body
Vídeo curto com ainda mais dicas para escolher a linguagem de programação para o seu projeto! (2 minutos)

# data[].attributes.attachment_link.title
Como escolher a linguagem de programação ideal

# data[].attributes.body
Trade Off Processamento Memória. Vídeo meio longo (30 minutos) mas que explica bem o conceito!

# data[].attributes.body
Vídeo sobre o que é compilação e interpretação de código? Vantagens e desvantagens básicas. (6 minutos)

# data[].attributes.attachment_link.title
Qual a diferença entre código compilado e código interpretado?

# data[].attributes.body
Vídeo sobre os conceitos de Linguagem Compilada x Interpretada... como funcionam? (6 minutos)

# data[].attributes.attachment_link.title
3.3. Linguagem compilada vs  interpretada

# data[].attributes.body
Download do Interpretador Python e do Ambiente de Desenvolvimento IDLE. Usaremos ao longo do curso!

# data[].attributes.attachment_link.readable_text
Release Date: Jan. 14, 2022

This is the second maintenance release of Python 3.10

Python 3.10.2 is the newest major release of the Python programming language, and it contains many new features and optimizations.

This is a special bugfix release ahead of schedule to address a memory leak that was happening on certain function calls when using Cython. The memory leak consisted of a small constant amount of bytes in certain function calls from Cython code. Although in most cases this was not very noticeable, it was very impactful for long-running applications and certain usage patterns. Check bpo-46347 for more information.

Among the new major new features and changes so far:

PEP 623 -- Deprecate and prepare for the removal of the wstr member in PyUnicodeObject.

PEP 604 -- Allow writing union types as X | Y

PEP 612 -- Parameter Specification Variables

PEP 626 -- Precise line numbers for debugging and other tools.

PEP 618 -- Add Optional Length-Checking To zip.

bpo-12782: Parenthesized context managers are now officially allowed.

PEP 632 -- Deprecate distutils module.

PEP 613 -- Explicit Type Aliases

PEP 634 -- Structural Pattern Matching: Specification

PEP 635 -- Structural Pattern Matching: Motivation and Rationale

PEP 636 -- Structural Pattern Matching: Tutorial

PEP 644 -- Require OpenSSL 1.1.1 or newer

PEP 624 -- Remove Py_UNICODE encoder APIs

PEP 597 -- Add optional EncodingWarning

bpo-38605: from __future__ import annotations ( PEP 563) used to be on this list in previous pre-releases but it has been postponed to Python 3.11 due to some compatibility concerns. You can read the Steering Council communication about it here to learn more.

The Carnot cycle is a theoretical ideal thermodynamic cycle proposed by French physicist Sadi Carnot in 1824 and expanded upon by others in the 1830s and 1840s. It provides an upper limit on the efficiency that any classical thermodynamic engine can achieve during the conversion of heat into work, or conversely, the efficiency of a refrigeration system in creating a temperature difference by the application of work to the system. It is not an actual thermodynamic cycle but is a theoretical construct.
Full Changelog

# data[].attributes.attachment_link.keywords[]
python programming language object oriented web free open source software license documentation download community

# data[].attributes.attachment_link.description
Release Date: Jan. 14, 2022 Python 3.10.2 is the newest major release of the Python programming language, and it contains many new features and optimizations. This is a special bugfix release ahead of schedule to address a memory leak that was happening on certain function calls when using Cython .

# data[].attributes.body
Depois de assistir à Aula 02 com o professor e os conteúdos do Pós Aula 02,  participe do desafio! (Disponível de 22/02/2022 até 03/02/2022).

# data[].attributes.body
Um vídeo curto, embora complexo, sobre o trade-off espaço-tempo.

# data[].attributes.attachment_link.title
Trade-off de espaço-tempo | Ciência da Computação | Khan Academy

# data[].attributes.body
O que é um compilador? Vídeo curto que fala um pouco mais sobre o processo de compilação.

# data[].attributes.body
Vídeo de 15 minutos que detalha um pouco mais como funciona um compilador por dentro.

# data[].attributes.attachment_link.title
"Como funciona um Compilador?" - Drops 04

# data[].attributes.body
Vídeo curto que explica o conceito de variáveis de uma maneira muito simples, com base na linguagem Java.

# data[].attributes.body
Vídeo bastante curto que explica o funcionamento das variáveis em Python.

# data[].attributes.body
Vídeo curto que explica o funcionamento das variáveis em Python, incluindo as regras de nomenclatura.

# data[].attributes.attachment_link.title
AULA 07 - O que são VARIÁVEIS E ATRIBUIÇÕES? — Curso de Python Grátis

# data[].attributes.body
Depois de assistir à Aula 03 com o professor e os conteúdos do Pós Aula 03,  participe do desafio! (Disponível de 04/03/2022 até 14/03/2022)

# data[].attributes.body
Texto: As falhas numéricas que podem causar desastres. Os problemas que a escolha incorreta de espaço para as variáveis podem trazer (15 minutos).

# data[].attributes.attachment_link.readable_text
4 de junho de 1996 será para sempre lembrado como um dia sombrio para a Agência Espacial Europeia. O primeiro voo não tripulado do foguete Ariane 5, que decolou carregando quatro satélites científicos caríssimos, acabou 39 segundos depois do lançamento, em uma horrível bola de fogo e fumaça. Estima-se que a explosão causou um prejuízo de US$ 370 milhões.

Não foi uma falha mecânica nem um ato de sabotagem. O desastre foi causado por um simples bug em um software, que fez cálculos errados ao se tornar sobrecarregado com números mais longos do que era capaz de suportar.

Erros semelhantes foram também os responsáveis por uma série de incidentes nos últimos anos, fazendo sondas espaciais desaparecerem ou desviando mísseis de seus alvos.

Mas como é possível que computadores fiquem tão embaralhados com números? E o que causa esses bugs?
Leia mais: Quando encontraremos seres alienígenas? Leia mais: Será que um dia viveremos debaixo da terra?
'Virada' perigosa

Imagine tentar representar um valor de, por exemplo, 105.350 quilômetros em um hodômetro que tem um valor máximo de 99.999. O contador "viraria" para 00.000 e contaria até 5.350, a quantia restante. Foi esse mesmo tipo de imprecisão que condenou o lançamento do Ariane 5.

Tecnicamente, o problema é chamado de "estouro de inteiros", o que significa que os números são muito longos para serem armazenados em um sistema computacional, às vezes provocando seu mau funcionamento.

Uma investigação do incidente com o foguete europeu revelou que um processo deixado pelo software da geração anterior, o Ariane 4, capturou uma inesperada medida de velocidade no novo veículo - muito mais rápido que seu antecessor - e o software do Ariane 5 não conseguiu lidar com esse número tão grande.

Uma sequência de autodestruição foi iniciada e, segundos depois, acontecia a tragédia.

Esse tipo de falha ocorre com uma frequência surpreendente. Acredita-se que um dos motivos pelo qual a Nasa perdeu o contato com a sonda espacial Deep Impact, em 2013, foi o fato de seu software ter alcançado um inteiro.

A ameaça de 2.147.483.647

No início de maio, surgiu a notícia de que um Boeing 787 poderá sofrer um problema semelhante: a unidade de controle que gerencia a distribuição de energia para os motores do avião pode entrar automaticamente em um modo à prova de falhas - desligando as turbinas - se for deixada ligada por mais de 284 dias.

Hipoteticamente, os motores poderiam parar repentinamente em pleno voo.

A diretriz da Administração Federal de Aviação dos Estados Unidos em relação à questão estabelece que um contador no software da unidade de controle "estoure" depois desse período específico de tempo.

Apesar de a FAA e a Boeing terem se recusado a comentar o assunto para esta reportagem, alguns observadores amadores destacaram que, quando contados em centésimos de segundo, 248 dias equivalem ao número 2.147.483.647 - o que é um dado muito importante.

Isso porque 2.147.483.647 é o valor positivo máximo que pode ser armazenado por um registrador de 32 bits, instalado em muitos sistemas computacionais.

No caso do Ariane 5, o software estava usando um espaço de 16 bits, capaz de armazenar o valor máximo de 32.767.
Leia mais: Moda viral: as redes sociais acabarão com as passarelas?
'Economia' de dados

Mas se os números são infinitos, por que usamos espaços de armazenagem tão limitados? Basta lembramos que os computadores tradicionalmente demandam eficiência em todas as frentes.

Quando os primeiros modelos surgiram, o espaço de armazenamento costumava era bem mais caro e o processamento de grandes números era mais lento. Mas, mantendo-se alguns limites, como os contadores, os softwares rodavam com mais facilidade.

Sistemas de foguetes teleguiados processam uma quantidade enorme de números a uma grande velocidade, por isso essa capacidade realmente importa. Mas até o desastre com o Ariane 5, essas limitações não eram vistas como problemáticas.

"Temos que reconhecer que, em termos de software, estamos sempre aproximando a realidade", explica Bill Scherlis, especialista da Universidade Carnegie Mellon, nos Estados Unidos. "A engenharia precisa encontrar um ponto de equilíbrio entre o custo de se ter uma contagem mais precisa e a eficiência com que o programa roda."

Efeitos inusitados

Mas nem todos os bugs de "estouro" de contadores são tão destrutivos. Alguns podem criar efeitos, no mínimo, inusitados.

No videogame Civilization, por exemplo, um defeito fez o pacífico personagem Gandhi se tornar inusitadamente hostil.

E em dezembro passado, o vídeo mais assistido na história do YouTube - Gangnam Style, do coreano Psy - "quebrou" o contador de visitas do site: aparentemente, o contador teria sido programado para ir, no máximo, até 2.147.483.647.

O YouTube se beneficiou da propaganda grátis gerada pela notícia e atualizou seu contador para suportar mais de 9 quintilhões visitantes.

O caso mais famoso de "estouro" da história foi, provavelmente, o chamado Bug do Milênio, que causou alguma dor de cabeça quando se percebeu que muitos computadores ainda registravam anos por seus dois últimos dígitos.

A maioria dos engenheiros e programadores conseguiu atualizar seus sistemas antes de 1º de janeiro de 2000, mas houve alguns incidentes interessantes: no Estado americano de Delaware, 150 máquinas caça-níqueis pararam de funcionar, o equipamento de detecção de radiação da cidade japonesa de Ishikawa entrou em pane, e vários sites exibiram a data "1º de janeiro de 19100".
Leia mais: Por que ainda não temos carros voadores?
O ano 2038

Há cerca de 15 anos, o programador William Porquet teve a ideia de pensar em outro momento que será crucial para o mundo da computação: as 3h14m07s da manhã de terça-feira 19 de janeiro de 2038 (horário de Greenwich).

Será nesse instante que o número de segundos contados desde 1º de janeiro de 1970 vai ultrapassar um dos valores máximos capazes de ser armazenados nos registradores de muitos computadores de hoje. Segundo Porquet, quem não se preparar poderá enfrentar falhas.

Sua maior preocupação é com softwares antigos que há anos não são atualizados, como os que controlam redes de distribuição de serviços, e com equipamentos velhos que ainda estão em uso em áreas remotas do planeta.

Já Markus Kuhn, cientista da computação na Universidade de Cambridge, na Grã-Bretanha, está mais interessado em resolver um problema que poderá acontecer agora em junho, quando será adicionado um segundo ao ano de 2015 para corrigir a discrepância entre a hora astronômica (baseada no tempo de rotação da Terra) e a hora atômica (um método mais preciso de contar a passagem do tempo).

A diferença ocorre porque a rotação terrestre está gradualmente se desacelerando. Eventos geológicos, como um terremoto, podem alterar essa velocidade, o que significa que o acréscimo de segundos a um ano é algo variável.

O último ocorreu em 2012 e deixou muitos computadores em pane.
Leia mais: Os shopping centers estão fadados a sumir do mapa americano? Leia a versão original desta reportagem em inglês no site BBC Future.

# data[].attributes.attachment_link.title
As falhas numéricas que podem causar desastres

# data[].attributes.attachment_link.description
4 de junho de 1996 será para sempre lembrado como um dia sombrio para a Agência Espacial Europeia. O primeiro voo não tripulado do foguete Ariane 5, que decolou carregando quatro satélites científicos caríssimos, acabou 39 segundos depois do lançamento, em uma horrível bola de fogo e fumaça.

# data[].attributes.body
Vídeo que mostra como é a representação de números em ponto flutuante em binário e algumas das fontes de erros (10 minutos).

# data[].attributes.body
Console Python para executar na web!

# data[].attributes.attachment_link.keywords[]
python programming language object oriented web free open source software license documentation download community

# data[].attributes.attachment_link.description
The official home of the Python Programming Language

# data[].attributes.body
Ambiente de programação online e compilação em várias linguagens!

# data[].attributes.attachment_link.title
C, C++, Java, Python, PHP Online Compliers, Terminals and Editors

# data[].attributes.attachment_link.description
C, C++, Java, Python, PHP Online Compliers, Terminals and Editors for Software Developers - Edit, Compile, Execute and Share Programs Online to experience the best cloud computing where you can edit, compile, execute and share your varities of projects with the help of simple clicks.

# data[].attributes.body
Vídeo que explica escopo de variáveis em Python (7 minutos)

# data[].attributes.attachment_link.title
Variáveis em Python - Curso de Python #03

# data[].attributes.body
Vídeo que explica escopo de variáveis em Java (8 minutos)

# data[].attributes.attachment_link.title
O que você não sabia sobre Escopo de Variável !

# data[].attributes.body
Vídeo curto que explica o básico das estrutura de decisão if-else (3 minutos).

# data[].attributes.attachment_link.title
4.1 If - Controle de Fluxo (Parte 1) - Python 3 Tutorial

# data[].attributes.body
Vídeo curto explicando o básico das estruturas de repetição while e for (4 minutos).

# data[].attributes.attachment_link.title
Curso Introdutório de Python Parte 7 de 17: Estruturas de Repetição

# data[].attributes.body
Depois de assistir à Aula 04 com o professor e os conteúdos associados à Aula 04, participe do desafio! (Disponível de 11/03/2022 a  21/03/2022)

# data[].attributes.body
Vídeo apresentando as estruturas de decisão: if, elif e else. (10 minutos).

# data[].attributes.attachment_link.title
4.1 else, elif - Controle de Fluxo (Parte 2) - Python 3 Tutorial

# data[].attributes.body
Vídeo longo explicando o que é escopo e como ele se aplica às variáveis. (18 minutos)

# data[].attributes.attachment_link.title
Linguagens de Programação - Aula 12 - Escopo de Identificadores

# data[].attributes.body
Vídeo longo que explica as diferenças práticas entre escopo estático e dinâmico.  (25 minutos)

# data[].attributes.attachment_link.title
Linguagens de Programação - Aula 13 - Escopo Estático e Dinâmico

# data[].attributes.body
Texto: Por que evitar as variáveis globais e como. (15 minutos)

# data[].attributes.attachment_link.provider_name
Embarcados - Sua fonte de informações sobre Sistemas Embarcados

# data[].attributes.attachment_link.readable_text
Em um artigo publicado em 1973 por Wulf e Shaw [1] foi descrito que o uso indiscriminado de variáveis globais é prejudicial. O problema independe da linguagem de programação: as variáveis globais são danosas desde a linguagem de baixo nível até as mais altas. E os mais jovens acabam aprendendo sobre isso quando entram em contato com comunidades de programação, livro do Jack Ganslee [2] ou errando nos projetos da empresa. Em 2011 houveram problemas com a Toyota Camry, e foi apontado que uma das causas era o uso de 11.000 variáveis globais [3] [4].

Mas qual é exatamente o problema das variáveis globais? Para quem já trabalhou em algum projeto sabe que é fácil chegar a mil ou duas mil linhas de código, ficando pouco a pouco mais difícil de cumprir o fluxograma inicial ou diagrama de estados planejado. Uma das razões é devido ao fato de várias funções e interrupções terem livre acesso às variáveis globais, gerando estados não existentes ao inicialmente planejado.

Para quem viveu numa república durante a faculdade vai entender com o seguinte exemplo: todos têm acesso à geladeira, certo? Você chega de noite, coloca o pudim que comprou dentro da geladeira, e espera o dia seguinte para comê-lo depois do almoço. E o que acontece? O seu "irmão" come o pudim antes porque teve livre acesso a ele. E ainda é provável de você ser chamado de "o vacilão".

Uma das formas de evitar as variáveis globais é logicamente utilizar as variáveis locais e implementar funções com passagem de valor. Veja o exemplo abaixo, adaptado para o caso do pudim na república:

A variável é vista somente dentro de e a função paulaEatsPudding() tem acesso à variável. Você pode prever o que vai acontecer com a variável de acordo com a ordem de execução ao estilo polling no , porém ao implementar as interrupções no código, o programador começa a coçar a cabeça, uma vez que não é possível fazer passagem de valor às interrupções.

Isso seria a mesma coisa que, para proteger o pudim, a Paula tivesse que esperar em frente a geladeira até a hora que ficar com fome, vigiando se alguém não vá pegar antes dela. Somando a isso, e se um colega de quarto dela pedisse um pedaço também?

Na próxima parte irei mostrar uma solução utilizando-se de modificadores de acesso e flags na linguagem C.
"Bilhete" para limitar o acesso e "sinalizações" para avisar quem foi que comeu
Agora vamos imaginar a seguinte situação: a Paula comprou o pudim ( ), guardou dentro da geladeira ( ) e foi para o seu quarto ( ). Mas a Diana, a sua colega de quarto e melhor amiga, viu o pudim e perguntou para a Paula se poderia comer também, quando estivesse com fome. A Paula, muito boazinha, deixou. Vamos interpretar a fome das duas como se fossem dois bits de uma interrupção de fome ( interrupt_Hunger() de ). O código ficaria da seguinte maneira:

Arquivo main.c:

Arquivo room.h:

Arquivo room.c:

O modificador static torna a variável global visível somente no arquivo em que é declarado ( ), e na república ficou estabelecido que somente as duas teriam acesso ao pudim (linha 15 do ). Elas podem ficar no quarto delas ( ) até a hora em que a fome bater ( interrupt_Hunger() ).

As interrupções somente avisam que algo aconteceu, mas não fazem o processamento complexo de alguma variável. No exemplo, utilizamos as interrupções para manipular somente as /sinalizações, para que o processamento dos dados principais ( . Isso de certa forma evita a descaracterização do fluxo lógico ou a criação de um estado inexistente na máquina de estados, como também segue o pudding = eatTheFood(pudding); ) seja feito no loop do princípio de responsabilidade única.

Note também que no iriam ser falsas. Porém, utilizando o operador binário "&" será verdadeiro nos dois casos. Veja o artigo do Fábio Souza a respeito de interrupt_Hunger() do arquivo não foi usado a comparação "==", mas sim o operador binário "&", pois se as duas interrupções ocorressem simultaneamente, na comparação "==" os dois casos coloquei o caso da Paula primeiro, pois caso as duas interrupções ocorram, ela irá comer primeiro (porque foi ela quem comprou o pudim), e a Diana comerá se sobrar algum pedaço (o que não vai acontecer no exemplo pois só há um pedaço). manipulação de bits. No loop do

Caso as duas interrupções viessem de registradores diferentes, seria necessário configurar a Caso duas ou mais interrupções ocorram, a de maior prioridade é executada antes e a de menor depois. Se as duas estivessem com fome simultaneamente, a Paula teria a prioridade e comeria o pudim. No caso de firmware multithreads deve-se usar a exclusão mútua (Mutex) para evitar que duas ou mais threads modifiquem uma variável ao mesmo tempo. O Felipe Neves já escreveu um prioridade das interrupções para não haver conflito de simultaneidade: artigo muito legal tratando sobre isso.

Tecnicamente falando, a variável poderia estar dentro do sendo uma , permanecerá existindo. No artigo do Fernando é explicado mais detalhadamente sobre o variável local sem o static. A diferença entre a variável local e a static é que a primeira é apagada do stack da memória RAM quando a função que a usa finaliza o seu serviço. Mas como a variável local estará dentro de modificador static e mostra um uso alternativo nas funções.

"Uso medicinal" das variáveis globais

Praticamente em duas situações você pode usar as variáveis globais:

Quando é uma constante: Bits de configuração de registrador, constantes matemáticas como π, valores de referências fixas que nunca mudam. É aconselhável utilizar modificador const ou macros #define por segurança. Fernando Deluno Garcia fez alguns artigos relacionados a isso em linguagem C [9] [10]. Você pode deixar essas constantes listadas em um arquivo header para não poluir visualmente o arquivo principal.

Valores de referência para todo o programa: Por exemplo, velocidade de um motor que deve servir de referência para muitas funções e módulos. Essas variáveis não podem ser duplicadas e deve ser utilizado o modificador volatile para que o valor se propague pelo fluxo lógico.

Conclusão

Gostaria de deixar claro que esses exemplos não são métodos infalíveis de se evitar bugs no código. Um profissional da área pode perceber falhas nos exemplos acima, mas como é um exemplo generalista, não quis entrar em detalhes para não deixar mais enfadonho para o estudante que está vendo isso pela primeira vez. O ponto principal do artigo é: reduzindo o escopo das variáveis torna o código mais seguro a bugs . A solução básica é utilizando variáveis locais e funções com passagem de valor. Eu quis também mostrar uma solução alternativa para quando conceitos como interrupção e modularização entram em jogo. Por se tratar de uma solução que exige mais da memória, o programador deve tomar cuidado e alocar corretamente o tamanho stack e heap da RAM.

Espero que tenham gostado do artigo, e se você conhece alguma técnica alternativa para evitar as variáveis globais, escreva nos comentários! Deem uma olhada nas referências abaixo, principalmente nos artigos do Embarcados, pois temos bastante material de excelente qualidade, ensinando a escrever códigos profissionais.
Referências
[1] WULF, W.; SHAW, M.; GLOBAL VARIABLE CONSIDERED HARMFUL, Carnegie-Mellon University, Pittsburg, Fev. 1973.

[2] Ganssle, J.; The Art of Designing Embedded Systems, Newnes, 2000.

[3] "Toyota Unintended Acceleration and the Big Bowl of "Spaghetti" Code" por Safety Research & Strategies INC.

[4] "Editorial: Custo do firmware" por Equipe Embarcados

[5] "Princípio da Responsabilidade Única em Firmwares" por Felipe Lavratti

[6] "Bits em Linguagem C - Conceito e Aplicação" por Fábio Souza

[7] "Como utilizar os semáforos para compartilhar recursos no mbed OS" por Felipe Neves

[8] "Como utilizar os semáforos para compartilhar recursos no mbed OS" por Fernando Deluno Garcia

[9] "Modificadores de Acesso na Linguagem C" por Fernando Deluno Garcia

[10] "Pré-processador C - Parte 1" por Fernando Deluno Garcia

[11] "Better Embedded System SW - Minimize Use of Global Variables" por Phil Koopman

[12] "Ponteiro em C: Definição" por Fernando Deluno Garcia

[13] "Programação Modular em C" por Fernando Deluno Garcia

[14] "Arquitetura de desenvolvimento de software - parte I" por Rodrigo Almeida

[15] "Máquina de estado" por Pedro Bertoleti

[16] "Regras do Contexto de Interrupção em Kernel Space" por Felipe Lavratti

# data[].attributes.attachment_link.title
Por que evitar as variáveis globais e como

# data[].attributes.attachment_link.description
Em um artigo publicado em 1973 por Wulf e Shaw [1] foi descrito que o uso indiscriminado de variáveis globais é prejudicial. O problema independe da linguagem de programação: as variáveis globais são danosas desde a linguagem de baixo nível até as mais altas.

# data[].attributes.body
Vídeo que explica o conceitos e coloca exemplos de tipos primitivos em python. (10 minutos)

# data[].attributes.body
Vídeo curto com o básico de strings e texto em Python. (4 minutos)

# data[].attributes.body
Vídeo curto com o básico de matrizes em Python. (6 minutos)

# data[].attributes.attachment_link.title
Curso de Python 09 - Aprendendo sobre Matrizes | Prime Cursos Grátis

# data[].attributes.body
Depois de assistir à Aula 05 com o professor e os conteúdos do Aula 05 - A Seguir...,  participe do desafio! (Disponível de 18/03/2022 a  28/03/2022)

# data[].attributes.body
Strings em Python - Vídeo mais longo com maior detalhamento sobre Strings na linguagem Python (15 minutos).

# data[].attributes.body
Vídeo sobre manipulação de strings em Python (11 minutos).

# data[].attributes.body
Matrizes em Python - Vídeo mais longo sobre matrizes na linguagem Python (20 minutos).

# data[].attributes.body
Codificação BCD - Vídeo curto que explica como funciona! (4 minutos)

# data[].attributes.body
Números de Ponto Flutuante: vídeo que explica como funciona o armazenamento de números em ponto flutuante (12 minutos).

# data[].attributes.body
O que são Registros e como funcionam. Vídeo que explica detalhadamente o funcionamento (15 minutos).

# data[].attributes.attachment_link.title
Registros - Lógica de Programação - AULA 19

# data[].attributes.body
Tuplas em Python. Vídeo curto explicando o conceito básico (6 minutos).

# data[].attributes.attachment_link.title
Curso de Python - Aula 52 - tuplas - eXcript

# data[].attributes.body
Depois de assistir à Aula 06 com o professor e os conteúdos do Pós Aula 06,  participe do desafio! (Disponível de 25/03/2022 a  28/04/2022)

# data[].attributes.body
Mais operações com listas. Texto com muitos exemplos e situações (25 minutos).

# data[].attributes.attachment_link.readable_text
Uma professora de matemática elaborou uma técnica de avaliação diferente, em uma tentativa de aumentar a interação entre os alunos para a próxima prova, a nota de todos seria a mesma, equivalente à média de todas as notas.

Todo esse processo seria feito por um sistema automático em Python. As notas dos alunos da sala avaliada foram arquivadas em uma estrutura de lista:

A fórmula para calcular a média aritmética de uma lista de números é a soma dos números dividida pela quantidade de números. Precisamos, então, descobrir duas coisas: a soma das notas e a quantidade de notas.

Somando todos os elementos de uma lista

Para somar todos os elementos da lista, vamos começar inicializando nossa variável que conterá o resultado da soma das notas com o valor 0, indicando que a soma ainda não foi feita:

Assim, uma abordagem que podemos seguir é através da iteração sobre as notas - para cada nota, soma-se seu valor à variável soma_das_notas, dessa forma:

for nota in notas: soma_das_notas += nota print(soma_das_notas)

E o resultado da soma:

Funciona perfeitamente! Mas será que não há uma maneira mais simples de somar todos os elementos de uma lista?

Somando os elementos de uma lista com a função sum()

Somar todos os elementos de algum conjunto é uma tarefa bastante comum em programação. Sendo assim, o Python também tem uma função nativa dedicada ao cálculo da soma de todos os elementos de uma lista - a função sum()!

Vamos usar essa nova abordagem:

Novamente, o resultado esperado:

Não só é mais simples usar a função sum() do que implementar um algoritmo de soma nós mesmos, como sua performance é muito melhor - um loop for é executado como Python interpretado, enquanto a função sum() é escrita puramente na linguagem C.

Agora que já sabemos a soma das notas, precisamos descobrir a quantidade delas.

Descobrindo o tamanho de uma lista com a função len()

A quantidade de notas é o tamanho da lista. Podemos, é claro, contar nós mesmos e armazenarmos essa contagem nossa em uma variável:

Tudo bem, mas essa abordagem seria problemática caso a lista mudasse de tamanho, ou até mesmo se a lista fosse maior (imagine contar número a número em uma lista de mais de 100 elementos!)

Se já trabalhamos com outras linguagens de programação, provavelmente vimos que geralmente há uma maneira nativa mais simples para se calcular o tamanho de uma lista. No Python isso não é diferente!

A função built-in retorna o comprimento de um objeto cuja classe implemente o [método len()](https://docs.python.org/3/reference/datamodel.html#object.__len__) , como por exemplo uma string, ou, no nosso caso, uma lista. Vamos testá-la com nossas notas:

E o resultado é o esperado:

Calculando a média aritmética

Agora que temos os dois valores que precisávamos, vamos calcular a média utilizando a fórmula soma_dos_numeros / quantidade_de_numeros:

media_das_notas = soma_das_notas / qtd_de_notas print(media_das_notas)

Agora já temos a média:

O resultado foi divulgado aos alunos, que responderam com reclamações - a nota foi mais baixa do que o esperado.

Depois de uma análise das notas, descobrimos que a média estava sendo calculada com a nota 0 de dois alunos que faltaram no dia da prova, o que não era justo!

Precisamos, então, remover essas notas 0 de nossa lista e recalcular a média.

Removendo um elemento de uma lista com o método remove()

Agora que já temos nossa lista completa, como podemos remover um elemento de dentro dela? Para isso, o Python nos traz o método , que recebe como parâmetro o valor que queremos remover de nossa lista. Vamos testar:

E o resultado:

[0, 9.0, 8.0, 5.0, 10.0, 7.0, 0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

Ok! Conseguimos remover um dos 0, mas o outro ainda ficou. Por que será? Acontece que o método remove() remove apenas o primeiro elemento encontrado cujo valor é igual ao parâmetro passado, não todos os elementos com esse valor.

Precisamos, então, chamar o método remove() duas vezes? Tudo bem, isso daria certo, mas e se, em vez de duas, tivéssemos dez notas 0. Será que realmente precisaríamos repetir uma mesma linha de código dez vezes? Isso não parece o ideal.

Conhecendo o Python e lógica de programação, uma abordagem intuitiva para esse problema seria iterar sobre a lista com um loop for e remover o valor caso ele seja igual a 0, para não precisarmos nos preocupar com a quantidade de notas 0. Vamos tentar:

E o resultado:

[0, 9.0, 8.0, 5.0, 10.0, 7.0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

Ué! De novo sobrou um 0! Por quê, dessa vez? Nesse caso, o que houve foi uma confusão entre o laço for e o método remove().

O for itera sobre os elementos de uma lista através do índice - ou seja, ele começa com o elemento na posição 0, passa pro elemento na posição 1 e assim por diante, até que o índice (a posição) atinja o comprimento da lista.

O método remove(), por sua vez, ao apagar um elemento, realoca os outros dentro da lista para que não haja um espaço vazio no lugar onde havia o elemento removido. Quando removemos um elemento da lista, a lista realmente diminui de tamanho!

Sabendo disso, vamos fazer uma simulação passo a passo para tentar entender o que aconteceu:

PRIMEIRO LOOP: índice = 0 lista = [ 0, 0, 9.0, 8.0, 5.0, 10.0, 7.0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

SEGUNDO LOOP: índice = 1 lista = [ 0, 9.0, 8.0, 5.0, 10.0, 7.0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

Note que o segundo 0 foi ignorado pelo for! Quando o for chegou no índice 1, onde estava esse 0 inicialmente, o 0 já havia sido realocado para o índice 0, resultando nesse problema.

Por isso, devemos sempre lembrar que é recomendável nunca alterar uma lista enquanto se itera sobre ela!

Precisamos de uma forma melhor de remover todas as ocorrências de um mesmo valor em uma lista.

Filtrando uma lista utilizando list comprehensions

Já conhecemos uma técnica no Python chamada de compreensão de lista. Como podemos usá-la para resolver nosso problema? Queremos uma lista com todos os valores da nossa lista de notas, contanto que o valor seja maior que 0.

Vamos lá, então:

E agora sim:

[9.0, 8.0, 5.0, 10.0, 7.0, 7.5, 4.0, 10.0, 7.0, 7.0, 8.0, 8.0, 7.5]

Enfim, basta recalcularmos a média com essa nova lista de notas:

media_valida = sum(notas_validas) / len(notas_validas) print(media_valida)

Dessa vez, uma média melhor para os alunos:

7.538461538461538

Após a média ser calculada e arredondada para 7.5, a professora quis conferir se seu método de avaliação tinha sido efetivo - isto é, se a nota da sala realmente representava como os alunos tinham se saído na prova.

Para isso, ela precisava calcular quantos alunos tiraram a nota na média, com uma margem de diferença de 0.5 (ou seja, quantos alunos tiraram uma nota entre 7 e 8).

Contando elementos em uma lista com o método count()

Para contar quantas vezes um elemento aparece numa lista, podemos usar o método count() dessa forma:

qtd_de_setes = notas.count(7.0) print(qtd_de_setes)

E o resultado:

Para de fato fazermos o que queremos precisamos usar o método com três valores - 7, 7.5 e 8:

qtd_alunos_na_media = notas.count(7.0) + notas.count(7.5) + notas.count(8.0) print(qtd_alunos_na_media)

O resultado:

Certo! No nosso caso, essa solução com o count() funciona bem, porque sabemos que são apenas esses três valores ( 7.0, 7.5 e 8.0) que queremos.

Mas e se nossa lista tivesse, por exemplo, valores como 7.1, 7.2... e assim em diante até 8.0. Teríamos que fazer um count() para cada um desses valores? Parece complicado, não é?

Uma outra abordagem que poderia ser utilizada, que evitaria o problema de haver mais valores no intervalo que queremos contar, seria utilizar um laço for e armazenar o valor da contagem em uma variável, dessa forma:

Temos o mesmo resultado:

Juntando o que aprendemos do método sum() e de compreensão de lista, e sabendo que no Python a classe bool, que representa os tipos booleanos, herda da classe int ( True é igual a 1 e False é igual a 0), podemos até fazer isso de uma forma bem mais sucinta:

Temos o mesmo resultado:

Conclusão

Nesse post pudemos ver a utilidade da listas, quando podemos usá-las e o que podemos fazer com elas.

Passamos por necessidades como remover todas as ocorrências de um valor na lista, somar todos os elementos da lista, saber o comprimento da lista e até remover todas as ocorrências de um elemento na lista, e conseguimos resolver uma a uma através de nossa lógica e das próprias funcionalidades do Python!

Para saber mais

Quer aprender mais sobre listas em Python? Dê uma olhada nos nossos outros posts no blog sobre o assunto e aprenda mais sobre adicionar elementos a uma lista, ordenar uma lista e até conheça a funcionalidade da compreensão de lista.

Além disso, pode ser legal dar uma lida na documentação das listas no Python, para conhecer mais possibilidades no tratamento delas.

Gostou do conteúdo? Está mais confiante para usar listas no Python, agora? Que tal aprender um pouco mais? Confira nossa formação Python para web e continue estudando!

Leia também:

# data[].attributes.attachment_link.title
Listas em Python: operações básicas | Alura Cursos Online

# data[].attributes.attachment_link.description
Uma professora de matemática elaborou uma técnica de avaliação diferente, em uma tentativa de aumentar a interação entre os alunos para a próxima prova, a nota de todos seria a mesma, equivalente à média de todas as notas. Todo esse processo seria feito por um sistema automático em Python.

# data[].attributes.body
Aprofundando o conceito de tuplas como registros. Vídeo longo (cerca de 50 minutos).

# data[].attributes.body
Tuplas e Tuplas Nomeadas em Python. Vídeo explicando como usar  (12 minutos).

# data[].attributes.attachment_link.title
Biblioteca padrão #1 - collections.namedtuple

# data[].attributes.body
Explicação do uso de tuplas com vários exemplos. Texto (40 minutos).

# data[].attributes.attachment_link.readable_text
Este capítulo apresenta mais um tipo integrado, a tupla, e descreve como as listas, os dicionários e as tuplas trabalham juntos. Além disso, apresento um recurso útil para listas de argumentos de comprimento variável: os operadores gather e scatter.

Uma observação: não há consenso sobre como pronunciar "tuple" (em inglês). Algumas pessoas dizem "tuhple", que rima com "supple". Porém, no contexto da programação, a maioria das pessoas diz "too-ple", que rima com "quadruple".

12.1 - Tuplas são imutáveis

Uma tupla é uma sequência de valores. Os valores podem ser de qualquer tipo, e podem ser indexados por números inteiros, portanto, nesse sentido, as tuplas são muito parecidas com as listas. A diferença importante é que as tuplas são imutáveis.

Sintaticamente, uma tupla é uma lista de valores separados por vírgulas:

Embora não seja sempre necessário, é comum colocar tuplas entre parênteses:

Para criar uma tupla com um único elemento, é preciso incluir uma vírgula final:

Um único valor entre parênteses não é uma tupla:

Outra forma de criar uma tupla é com a função integrada tuple. Sem argumentos, cria uma tupla vazia:

Se os argumentos forem uma sequência (string, lista ou tupla), o resultado é uma tupla com os elementos da sequência:

Como tuple é o nome de uma função integrada, você deve evitar usá-lo como nome de variável.

A maior parte dos operadores de lista também funciona em tuplas. O operador de colchetes indexa um elemento:

E o operador de fatia seleciona vários elementos:

Entretanto, se tentar alterar um dos elementos da tupla, vai receber um erro:

Como tuplas são imutáveis, você não pode alterar os elementos, mas pode substituir uma tupla por outra:

Essa instrução faz uma nova tupla e então a atribui a t.

Os operadores relacionais funcionam com tuplas e outras sequências; o Python começa comparando o primeiro elemento de cada sequência. Se forem iguais, vai para os próximos elementos, e assim por diante, até que encontre elementos que sejam diferentes. Os elementos subsequentes não são considerados (mesmo se forem muito grandes).

12.2 - Atribuição de tuplas

Muitas vezes, é útil trocar os valores de duas variáveis. Com a atribuição convencional, é preciso usar uma variável temporária. Por exemplo, trocar a e b.

Essa solução é trabalhosa; a atribuição de tuplas é mais elegante:

O lado esquerdo é uma tupla de variáveis; o lado direito é uma tupla de expressões. Cada valor é atribuído à sua respectiva variável. Todas as expressões no lado direito são avaliadas antes de todas as atribuições.

O número de variáveis à esquerda e o número de valores à direita precisam ser iguais:

De forma geral, o lado direito pode ter qualquer tipo de sequência (string, lista ou tupla). Por exemplo, para dividir um endereço de email em um nome de usuário e um domínio, você poderia escrever:

O valor de retorno do split é uma lista com dois elementos; o primeiro elemento é atribuído a uname, o segundo a domain:

12.3 - Tuplas como valores de retorno

Falando estritamente, uma função só pode retornar um valor, mas se o valor for uma tupla, o efeito é o mesmo que retornar valores múltiplos. Por exemplo, se você quiser dividir dois números inteiros e calcular o quociente e resto, não é eficiente calcular x/y e depois x%y. É melhor calcular ambos ao mesmo tempo.

A função integrada divmod toma dois argumentos e devolve uma tupla de dois valores: o quociente e o resto. Você pode guardar o resultado como uma tupla:

Ou usar a atribuição de tuplas para guardar os elementos separadamente:

Aqui está um exemplo de função que retorna uma tupla:

max e min são funções integradas que encontram os maiores e menores elementos de uma sequência. min_max calcula ambos e retorna uma tupla de dois valores.

12.4 - Tuplas com argumentos de comprimento variável

As funções podem receber um número variável de argumentos. Um nome de parâmetro que comece com * reúne vários argumentos em uma tupla. Por exemplo, printall recebe qualquer número de argumentos e os exibe:

O parâmetro com o prefixo * pode ter qualquer nome que você goste, mas args é o convencional. É assim que a função funciona:

O complemento de reunir é espalhar. Se você tiver uma sequência de valores e quiser passá-la a uma função como argumentos múltiplos, pode usar o operador *. Por exemplo, o divmod recebe exatamente dois argumentos; ele não funciona com uma tupla:

No entanto, se você espalhar a tupla, aí funciona:

Muitas das funções integradas usam tuplas com argumentos de comprimento variável. Por exemplo, max e min podem receber qualquer número de argumentos:

Mas sum, não:

Como exercício, escreva uma função chamada sumall que receba qualquer número de argumentos e retorne a soma deles.

12.5 - Listas e tuplas

zip é uma função integrada que recebe duas ou mais sequências e devolve uma lista de tuplas onde cada tupla contém um elemento de cada sequência. O nome da função tem a ver com o zíper, que se junta e encaixa duas carreiras de dentes.

Este exemplo encaixa uma string e uma lista:

O resultado é um objeto zip que sabe como percorrer os pares. O uso mais comum de zip é em um loop for:

Um objeto zip é um tipo de iterador, ou seja, qualquer objeto que percorre ou itera sobre uma sequência. Iteradores são semelhantes a listas em alguns aspectos, mas, ao contrário de listas, não é possível usar um índice para selecionar um elemento de um iterador.

Se quiser usar operadores e métodos de lista, você pode usar um objeto zip para fazer uma lista:

O resultado é uma lista de tuplas; neste exemplo, cada tupla contém um caractere da string e o elemento correspondente da lista.

Se as sequências não forem do mesmo comprimento, o resultado tem o comprimento da mais curta:

Você pode usar a atribuição de tuplas em um loop for para atravessar uma lista de tuplas:

Cada vez que o programa passa pelo loop, o Python seleciona a próxima tupla na lista e atribui os elementos letter e number. A saída deste loop é:

Se combinar zip, for e atribuição de tuplas, você pode fazer uma expressão útil para percorrer duas (ou mais) sequências ao mesmo tempo. Por exemplo, has_match recebe duas sequências, t1 e t2 e retorna True se houver um índice i tal que t1[i] == t2[i]:

Se precisar atravessar os elementos de uma sequência e seus índices, você pode usar a função integrada enumerate:

O resultado de enumerate é um objeto enumerate, que itera sobre uma sequência de pares; cada par contém um índice (começando de 0) e um elemento da sequência dada. Neste exemplo, a saída é

De novo.

12.6 - Dicionários e tuplas

Os dicionários têm um método chamado items que devolve uma sequência de tuplas, onde cada tupla é um par chave-valor:

O resultado é um objeto dict_items, que é um iterador que percorre os pares chave-valor. Você pode usá-lo em um loop for, desta forma:

Como se poderia esperar de um dicionário, os itens não estão em nenhuma ordem em particular.

Indo em outra direção, você pode usar uma lista de tuplas para inicializar um novo dicionário:

Combinar dict com zip produz uma forma concisa de criar um dicionário:

O método de dicionário update também recebe uma lista de tuplas e as adiciona, como pares chave-valor, a um dicionário existente.

É comum usar tuplas como chaves em dicionários (principalmente porque você não pode usar listas). Por exemplo, uma lista telefônica poderia mapear pares de sobrenome e primeiro nome a números de telefone. Supondo que tenhamos definido last, first e number, podemos escrever:

A expressão entre chaves é uma tupla. Podemos usar atribuição de tuplas para atravessar este dicionário:

Este loop atravessa as chaves em directory, que são tuplas. Ele atribui os elementos de cada tupla para last e first, e então exibe o nome e número de telefone correspondente.

Há duas formas de representar tuplas em um diagrama de estado. A versão mais detalhada mostra os índices e elementos como aparecem em uma lista. Por exemplo, a tupla ('Cleese', 'John') apareceria como na Figura 12.1.

Figura 12.1 - Diagrama de estado de uma tupla.

No entanto, em um diagrama maior, você pode querer omitir os detalhes. Por exemplo, um diagrama da lista telefônica poderia ser como o da Figura 12.2.

Figura 12.2 - Diagrama de estado de um dicionário com chaves do tipo tupla.

Aqui as tuplas são mostradas usando a sintaxe do Python para simplificar o gráfico. O número de telefone no diagrama é a linha de reclamações da BBC, então, por favor, não ligue para lá.

12.7 - Sequências de sequências

Eu me concentrei em listas de tuplas, mas quase todos os exemplos neste capítulo também funcionam com listas de listas, tuplas de tuplas e tuplas de listas. Para evitar enumerar as combinações possíveis, às vezes é mais fácil falar sobre sequências de sequências.

Em muitos contextos, os tipos diferentes de sequências (strings, listas e tuplas) podem ser usados de forma intercambiável. Então, como escolher uma em vez da outra?

Para começar com o óbvio, as strings são mais limitadas que outras sequências porque os elementos têm de ser caracteres. Também são imutáveis. Se precisar da capacidade de alterar caracteres em uma string (em vez de criar outra string) você pode querer usar uma lista de caracteres.

As listas são mais comuns que as tuplas, principalmente porque são mutáveis. Mas há alguns casos em que você pode preferir tuplas:

1. Em alguns contextos, como em uma instrução return, é sintaticamente mais simples criar uma tupla que uma lista.

2. Se quiser usar uma sequência como uma chave de dicionário, é preciso usar um tipo imutável como uma tupla ou string.

3. Se estiver passando uma sequência como um argumento a uma função, usar tuplas reduz o potencial de comportamento inesperado devido a alias.

Como tuplas são imutáveis, elas não fornecem métodos como sort e reverse, que alteram listas existentes. Porém, o Python fornece a função integrada sorted, que recebe qualquer sequência e retorna uma nova lista com os mesmos elementos ordenados, e reversed, que recebe uma sequência e retorna um iterador que percorre a lista em ordem reversa.

12.8 - Depuração

As listas, os dicionários e as tuplas são exemplos de estruturas de dados; neste capítulo estamos começando a ver estruturas de dados compostas, como as listas de tuplas ou dicionários que contêm tuplas como chaves e listas como valores. As estruturas de dados compostas são úteis, mas são propensas ao que chamo de erros de forma; isto é, erros causados quando uma estrutura de dados tem o tipo, tamanho ou estrutura incorretos. Por exemplo, se você estiver esperando uma lista com um número inteiro e eu der apenas o número inteiro (não em uma lista), não vai funcionar.

Para ajudar a depurar esses tipos de erro, escrevi um módulo chamado structshape, que fornece uma função, também chamada structshape, que recebe qualquer tipo de estrutura de dados como argumento e retorna uma string, que resume sua forma. Você pode baixá-la em http://thinkpython2.com/code/structshape.py.

Aqui está o resultado de uma lista simples:

Um programa mais sofisticado pode escrever "list of 3 ints", mas é mais fácil não lidar com plurais. Aqui está uma lista de listas:

Se os elementos da lista não forem do mesmo tipo, structshape os agrupa, na ordem, por tipo:

Aqui está uma lista de tuplas:

E aqui está um dicionário com três itens que mapeia números inteiros a strings:

Se estiver com problemas para monitorar suas estruturas de dados, o structshape pode ajudar.

12.9 - Glossário

tupla

Sequência imutável de elementos.

atribuição de tupla

Atribuição com uma sequência no lado direito e uma tupla de variáveis à esquerda. O lado direito é avaliado e então seus elementos são atribuídos às variáveis à esquerda.

gather

Operação para montar uma tupla com argumento de comprimento variável.

scatter

Operação para tratar uma sequência como uma lista de argumentos.

objeto zip

O resultado de chamar uma função integrada zip; um objeto que se repete por uma sequência de tuplas.

iterador

Objeto que pode se repetir por uma sequência, mas que não oferece operadores de lista e métodos.

estrutura de dados

Coleção de valores relacionados, muitas vezes organizados em listas, dicionários, tuplas etc.

erro de forma

Erro causado pelo fato de o valor ter a forma incorreta; isto é, tipo ou tamanho incorreto.

12.10 - Exercícios

Exercício 12.1

Escreva uma função chamada most_frequent que receba uma string e exiba as letras em ordem decrescente de frequência. Encontre amostras de texto de vários idiomas diferentes e veja como a frequência das letras varia entre os idiomas. Compare seus resultados com as tabelas em http://en.wikipedia.org/wiki/Letter_frequencies.

Solução: http://thinkpython2.com/code/most_frequent.py.

Exercício 12.2

Mais anagramas!

Escreva um programa que leia uma lista de palavras de um arquivo (veja "Leitura de listas de palavras", na página 133) e imprima todos os conjuntos de palavras que são anagramas.

Aqui está um exemplo de como a saída pode parecer:

Dica: você pode querer construir um dicionário que mapeie uma coleção de letras a uma lista de palavras que podem ser soletradas com essas letras. A pergunta é: como representar a coleção de letras de forma que possa ser usada como uma chave?

1. Altere o programa anterior para que exiba a lista mais longa de anagramas primeiro, seguido pela segunda mais longa, e assim por diante.

2. No Scrabble, um "bingo" é quando você joga todas as sete peças na sua estante, junto com uma peça no tabuleiro, para formar uma palavra de oito letras. Que coleção de oito letras forma o maior número possível de bingos? Dica: há sete.

Solução: http://thinkpython2.com/code/anagram_sets.py.

Exercício 12.3

Duas palavras formam um "par de metátese" se você puder transformar uma na outra trocando duas letras, por exemplo, "converse" e "conserve". Escreva um programa que descubra todos os pares de metátese no dicionário. Dica: não teste todos os pares de palavras e não teste todas as trocas possíveis.

Solução: http://thinkpython2.com/code/metathesis.py. Crédito: este exercício foi inspirado por um exemplo em http://puzzlers.org.

Exercício 12.4

Aqui está outro quebra-cabeça do programa Car Talk (http://www.cartalk.com/content/puzzlers):

Qual é a palavra inglesa mais longa, que permanece uma palavra inglesa válida, conforme vai removendo suas letras, uma após a outra?

Agora, as letras podem ser retiradas do fim ou do meio, mas você não pode reajustar nenhuma delas. Cada vez que remove uma letra, você acaba com outra palavra inglesa. Se fizer isto, eventualmente você acabará com uma letra e isso também será uma palavra inglesa; uma encontrada no dicionário. Quero saber qual é a palavra mais longa e quantas letras tem?

Vou dar um pequeno exemplo modesto: Sprite. Ok? Você começa com sprite, tira uma letra do interior da palavra, tira o r, e ficamos com a palavra spite, então tiramos o e do fim, ficamos com spit, tiramos o s, ficamos com pit, it e I.

Escreva um programa que encontre todas as palavras que podem ser reduzidas desta forma, e então encontre a mais longa.

Este exercício é um pouco mais desafiador que a maioria, então aqui estão algumas sugestões:

1. Você pode querer escrever uma função que receba uma palavra e calcule uma lista de todas as palavras que podem ser formadas retirando uma letra. Esses são os "filhos" da palavra.

2. Recursivamente, uma palavra é redutível se algum de seus filhos for redutível. Como caso base, você pode considerar a string vazia redutível.

3. A lista de palavras que forneci, words.txt, não contém palavras de uma letra só. Portanto, você pode querer acrescentar "I", "a", e a string vazia.

4. Para melhorar o desempenho do seu programa, você pode querer memorizar as palavras conhecidas por serem redutíveis.

Solução: http://thinkpython2.com/code/reducible.py.

# data[].attributes.attachment_link.description
Este capítulo apresenta mais um tipo integrado, a tupla, e descreve como as listas, os dicionários e as tuplas trabalham juntos. Além disso, apresento um recurso útil para listas de argumentos de comprimento variável: os operadores gather e scatter. Uma observação: não há consenso sobre como pronunciar "tuple" (em inglês).

# data[].attributes.body
Mais aplicações de tuplas. Texto (25 minutos).

# data[].attributes.attachment_link.readable_text
Até agora, você tem visto dois tipos compostos: strings, que são compostos de caracteres; e listas, que são compostas de elementos de qualquer tipo. Uma das diferenças que notamos é que os elementos de uma lista podem ser modificados, mas os caracteres em uma string não. Em outras palavras, strings são imutáveis e listas são mutáveis.

Há um outro tipo em Python chamado tupla (tuple) que é similar a uma lista exceto por ele ser imutável. Sintaticamente, uma tupla é uma lista de valores separados por vírgulas:

Embora não seja necessário, é convencional colocar tuplas entre parênteses:

Para criar uma tupla com um único elemento, temos que incluir uma vírgula final:

Sem a vírgula, Python entende como uma string entre parênteses:

Questões de sintaxe de lado, as operações em tuplas são as mesmas operações das listas. O operador índice seleciona um elemento da tupla.

E o operador slice (fatia) seleciona uma "faixa" ( range) de elementos.

Mas se tentarmos modificar um dos elementos de uma tupla, teremos um erro:

Naturalmente, mesmo que não possamos modificar os elementos de uma tupla, podemos substituí-la por uma tupla diferente:

De vez em quando, é necessário trocar entre si os valores de duas variáveis. Com operações de atribuição convencionais, temos que utilizar uma variável temporária. Por exemplo, para fazer a troca entre e :

Se você tiver que fazer isso com frequência, esta abordagem se torna incômoda. Python fornece uma forma de atribuição de tupla que resolve esse problema elegantemente:

O lado esquedo é uma tupla de variáveis; o lado direito é uma tupla de valores. Cada valor é atribuído à sua respectiva variável. Todas as expressões do lado direito são avaliadas antes de qualquer das atribuições. Esta característica torna as atribuições de tupla bastante versáteis.

Naturalmente, o número de variáveis na esquerda e o número de valores na direita deve ser igual:

Funções podem retornar tuplas como valor de retorno. Por Exemplo, nós poderíamos escrever uma função que troca dois parâmetros entre si:

Então nós poderíamos atribuir o valor de retorno para uma tupla com duas variáveis:

Neste caso, não existe uma grande vantagem em fazer de ( swap) uma função. De fato, existe um perigo em tentar encapsular , o qual é a tentação de cometer o seguinte erro:

Se nós chamarmos esta função desta forma:

Esta função roda sem produzir uma mensagem de erro, mas ela não faz o que pretendemos. Este é um exemplo de um erro semântico.

Como exercício, desenhe um diagrama de estado pra esta função de modo que você possa ver porque ela não funciona.

A maioria dos programas de computador fazem a mesma coisa sempre que são executados, então, podemos dizer que eles são determinísticos. Determinismo em geral é uma coisa boa, se nós esperamos que um cálculo dê sempre o mesmo resultado. Entretanto, para algumas aplicações queremos que o computador se torne imprevisível. Jogos são um exemplo óbvio, mas existem outros.

Fazer um programa realmente não-determinístico se mostra não ser tão fácil, mas existem maneiras de fazê-lo ao menos parecer não-determinístico. Uma dessas maneiras é gerar números aleatórios e usá-los para determinar o resultado de um programa. Python tem uma função nativa que gera números pseudo aleatórios, os quais não são verdadeiramente aleatórios no sentido matemático, mas para os nossos propósitos eles são.

O módulo contém uma função chamada que retorna um número em ponto flutuante ( floating-point number) entre 0.0 e 1.0. Cada vez que você chama , você recebe o próximo número de uma longa série. Para ver uma amostra, execute este loop:

Para gerar um número aleatório ente 0.0 e um limite superior, digamos , multiplique por .

Como exercício, gere um número aleatório entre 'inferior' e 'superior'. Como exercício adicional, gere um número inteiro aleatório entre 'inferior' e 'superior', inclusive os dois extremos.

O primeiro passo é gerar uma lista aleatória de valores. listaAleatoria pega um parâmetro inteiro e retorna uma lista de números aleatórios com o comprimento dado. Inicia-se com uma lista de zeros. A cada iteração do loop, ele substitui um dos elementos por um número aleatório. O valor retornado é uma referência para a lista completa:

Vamos realizar um teste desta função com uma lista de oito elementos. Para efeitos de depuração, é uma boa idéia começar com uma lista pequena.

Os números gerados por são supostamente uniformemente distribuídos, o que significa que cada valor tem uma probabilidade igual de acontecer.

Se nós dividirmos a faixa de valores possíveis em intervalos do mesmo tamanho, e contarmos o número de vezes que um determinado valor aleatório caiu em seu respectivo intervalo, nós devemos obter o mesmo número aproximado de valores em cada um dos intervalos.

Nós podemos testar esta teoria escrevendo um programa que divida a faixa de valores em intervalos e conte o número de valores de cada intervalo.

Uma boa maneira de abordar problemas como esse é dividir o problema em subproblemas, e encontrar um subproblema que se enquadre em um padrão de solução computacional que você já tenha visto antes.

Neste caso, queremos percorrer uma lista de números e contar o número de vezes que valor se encaixa em um determinado intervalo. Isso soa familiar. Na Seção 7.8, nós escrevemos um programa que percorria uma string e contava o número de vezes que uma determinada letra aparecia.

Assim, podemos prosseguir copiando o programa original e adaptando-o para o problema atual. O programa original era:

O primeiro passo é substituir por e por . Isso não muda o programa, apenas o ajusta para que ele se torne mais fácil de ler e entender.

O segundo passo é mudar o teste. Nós não estamos interessados em procurar letras. Nós queremos ver se está entre e .:

O último passo é encapsular este código em uma função chamada noIntervalo . Os parâmetros são a lista e os valores e :

Através da cópia e da modificação de um programa existente, estamos aptos a escrever esta função rapidamente e economizar um bocado de tempo de depuração. Este plano de desenvolvimento é chamado de casamento de padrões. Se você se encontrar trabalhando em um problema que você já solucionou antes, reuse a solução.

Conforme o número de intervalos aumenta, noIntervalo torna-se intragável. Com dois intervalos, não é tão ruim:

Mas com quatro intervalos, começa a ficar desconfortável.:

Existem aqui dois problemas. Um é que temos que criar novos nomes de variável para cada resultado. O outro é que temos que calcular os limites de cada intervalo.

Vamos resolver o segundo problema primeiro. Se o número de intervalos é numeroDeIntervalos , então a largura de cada intervalo é 1.0 / numeroDeIntervalos .

Vamos usar um laço ( loop) para calcular a faixa, ou largura, de cada intervalo. A variável do loop, , conta de 0 até numeroDeIntervalos-1 :

Para calcular o limite inferior () de cada intervalo, nós multiplicamos a variável do loop () pela largura do intervalo ( larguraDoIntervalo ). O limite superior () está exatamente uma "largura de intervalo" acima.

Você pode confirmar que cada intervalo tem a mesma largura, que eles não se sobrepõe, e que eles cobrem toda a faixa de valores de 0.0 a 1.0.

Agora, de volta ao primeiro problema. Nós precisamos de uma maneira de guardar oito inteiros, usando a váriavel do loop para indicar cada um destes inteiros. Você deve estar pensando, "Lista!"

Nós temos que criar a lista de intervalos fora do loop, porque queremos fazer isto apenas uma vez. Dentro do loop, nós vamos chamar noIntervalo repetidamente e atualizar o -ésimo elemento da lista:

Com uma lista de 1000 valores, este código vai produzir esta lista de quantidades de valores em cada intervalo:

Esses números estão razoavelmente póximos de 125, o que era o que esperávamos. Pelo menos eles estão próximos o bastante para nos fazer acreditar que o gerador de número aleatórios está funcionando.

Como exercício, teste esta função com algumas listas longas, e veja se o número de valores em cada um dos intervalos tendem a uma distribuição nivelada.

Embora este programa funcione, ele não é tão eficiente quanto poderia ser. Toda vez que ele chama noIntervalo , ele percorre a lista inteira. Conforme o número de intervalos aumenta, a lista será percorrida um bocado de vezes.

Seria melhor fazer uma única passagem pela lista e calcular para cada valor o índice do intervalo ao qual o valor pertença. Então podemos incrementar o contador apropriado.

Na seção anterior, pegamos um índice, , e o multiplicamos pela larguraDoIntervalo para encontrar o limite inferior daquele intervalo. Agora queremos pegar um valor entre 0.0 e 1.0 e encontrar o índice do intervalo ao qual ele se encaixa.

Já que este problema é o inverso do problema anterior, podemos imaginar que deveríamos dividir por larguraDoIntervalo em vez de multiplicar. Esta suposição está correta.

Já que larguraDoIntervalo = 1.0 / numeroDeIntervalos, dividir por larguraDoIntervalo é o mesmo que multiplicar por numeroDeIntervalos . Se multiplicarmos um número na faixa entre 0.0 e 1.0 por numeroDeIntervalos , obtemos um número na faixa entre 0.0 e numeroDeIntervalos . Se arredondarmos este número para baixo, ou seja, para o menor inteiro mais próximo, obtemos exatamente o que estamos procurando - o índice do intervalo:

Usamos a função para converter um número em ponto flutuante ( float) para um inteiro.

Existe a possibilidade deste cálculo produzir um índice que esteja fora dos limites (seja negativo ou maior que len(intervalos)-1 )?

Uma lista como intervalos que contém uma contagem do número de valores em cada intervalo é chamada de histograma.

Como exercício, escreva uma função chamada ``histograma`` que receba uma lista e um número de intervalos como argumentos e retorne um histograma com o número de intervalos solicitado.

tipo imutável (immutable type)

Um tipo de elemento que não pode ser modificado. Atribuições a um elemento ou "fatiamento (slices)" XXX aos tipos imutáveis causarão erro.

tipo mutável (mutable type)

Tipo de dados onde os elementos podem ser modificados. Todos os tipos mutáveis, são tipos compostos. Listas e dicionários são exemplos de tipos de dados mutáveis. String e tuplas não são.

tupla (tuple)

Tipo sequencial similar as listas com exceção de que ele é imutável. Podem ser usadas Tuplas sempre que um tipo imutável for necessário, por exemplo uma "chave (key)" em um dicionário

Atribuição a tupla (tuple assignment)

Atribuição a todos os elementos de uma tupla feita num único comando de atribução. A atribuição aos elementos ocorre em paralelo, e não em sequência, tornando esta operação útil para swap, ou troca recíproca de valores entre variáveis (ex: a,b=b,a).

determinístico (deterministic)

Um programa que realiza a mesma coisa sempre que é executado.

pseudo aleatório (pseudorandom)

Uma sequência de números que parecem ser aleatórios mas são na verdade o resultado de uma computação "determinística"

histograma (histogram)

Uma lista de inteiros na qual cada elemento conta o número de vezes que algo acontece.

casamento de padrão XXX (pattern matching)

Um programa desenvolvido que envolve identificar um teste padrão computacional familiar e copiar a solução para um problema similar.

# data[].attributes.attachment_link.title
Capítulo 9: Tuplas - Documentação Aprenda Computação com Python 2 1.1

# data[].attributes.attachment_link.description
Até agora, você tem visto dois tipos compostos: strings, que são compostos de caracteres; e listas, que são compostas de elementos de qualquer tipo. Uma das diferenças que notamos é que os elementos de uma lista podem ser modificados, mas os caracteres em uma string não.

# data[].attributes.body
Revisão de endereços de variável e organização de memória. Vídeo curto (9 minutos).

# data[].attributes.attachment_link.title
Entendendo de vez ponteiros e alocação dinâmica em C/C++ #01

# data[].attributes.body
Ponteiros em C com código e conceituação básica. Vídeo curto (9 minutos).

# data[].attributes.attachment_link.title
[C] Aula 55 - Ponteiros - Parte 1- Conceitos

# data[].attributes.body
Alocação dinâmica de memória em C: conceituação básica. Vídeo curto (5 minutos).

# data[].attributes.attachment_link.title
[C] Aula 60 - Alocação Dinâmica - Parte 1 - Introdução

# data[].attributes.body
Definições de Listas Estáticas em C. Vídeo curto (6 minutos).

# data[].attributes.attachment_link.title
[ED] Aula 03 - Listas Parte 1 - Definição

# data[].attributes.body
Funcionamento de Listas Estáticas em C. Vídeo curto (5 minutos).

# data[].attributes.attachment_link.title
[ED] Aula 04 - Listas Parte 2 - Lista Estática Sequencial

# data[].attributes.body
Depois de assistir à Aula 07 com o professor e os conteúdos do Pós Aula 07,  participe do desafio! (Disponível de 01/04/2022 a  11/04/2022)

# data[].attributes.body
Implementando o básico de listas estáticas em C. Vídeo curto (6 minutos).

# data[].attributes.attachment_link.title
[ED] Aula 05 - Listas Parte 3 - Implementando Lista Estática

# data[].attributes.body
Analisando a lista estática em C. Vídeo curto (5 minutos).

# data[].attributes.attachment_link.title
[ED] Aula 06 - Listas Parte 4 - Informações da Lista Estática

# data[].attributes.body
Inserindo elementos na lista estática.

# data[].attributes.body
Removendo elementos na lista estática

# data[].attributes.body
Consultando elementos na lista estática.

# data[].attributes.attachment_link.title
[ED] Aula 09 - Listas Parte 7 -  Consulta na Lista Estática

# data[].attributes.body
Alocação dinâmica de memória em C: aplicação. Vídeo curto (8 minutos).

# data[].attributes.attachment_link.title
[C] Aula 62 - Alocação Dinâmica: malloc()

# data[].attributes.body
Listas Dinâmicas em C: conceitos. Vídeo curto (6 minutos).

# data[].attributes.body
Listas Dinâmicas em C: implementação. Vídeo curto (7 minutos).

# data[].attributes.attachment_link.title
[ED] Aula 11 - Lista Dinâmica Encadeada Parte 2 - Implementação

# data[].attributes.body
Depois de assistir à Aula 08 com o professor e os conteúdos do Pós Aula 08,  participe do desafio! (Disponível de 08/04/2022 a  05/05
/2022)

# data[].attributes.body
Analisando a lista dinâmica em C. Vídeo curto (4 minutos).

# data[].attributes.attachment_link.title
[ED] Aula 12 - Lista Dinâmica Encadeada Parte 3 - Informações

# data[].attributes.body
Inserindo elementos na lista dinâmica. Vídeo curto (12 minuutos).

# data[].attributes.attachment_link.title
Aula 13 - ED1 - Inserção na Lista Dinâmica

# data[].attributes.body
Removendo elementos na lista dinâmica. Vídeo curto (11 minutos).

# data[].attributes.attachment_link.title
Aula 14 - ED1 - Remoção na Lista Dinâmica

# data[].attributes.body
Consultando elementos na lista dinâmica. Vídeo curto (5 minutos).

# data[].attributes.attachment_link.title
[ED] Aula 15 - Lista Dinâmica Encadeada Parte 6 - Consulta

# data[].attributes.body
Expressões e Operadores Aritméticos em Python. Vídeo curto (10 minutos)

# data[].attributes.attachment_link.title
7 - Python - Operadores e Expressões Aritméticas.

# data[].attributes.body
Operadores Lógicos em Python. Matéria em texto e vídeo curto (6 minutos)

# data[].attributes.attachment_link.readable_text
Nesta aula estudaremos os operadores lógicos na linguagem Python. Aprenderemos também a definição de valor lógica, a definição de conjunção, disjunção e de sub-expressões lógicas.

INTRODUÇÃO AOS OPERADORES LÓGICOS

Os operadores lógicos unem expressões lógicas formando assim, uma nova expressão que é composta por 2 ou mais sub-expressões. O resultado lógico de expressões compostas será a relação entre as sub-expressões. Como estudamos, toda expressão lógica avaliada resultará num valor lógico e a relação entre vários valores lógicos é um outro valor lógico.

Quando estudamos os Operadores Relacionais aprendemos a obter o valor lógico entre 2 operandos, no caso, entre o operando que está a esquerda do operador e o operando que está a direita do Operador Relacional. Como resposta, obtemos valores do tipo Booleano, isto é, verdadeiro [ True] ou falso [ False].

Os operadores lógicos por sua vez, permite-nos unir 2 expressões ligando-as com os conectivos lógicos matemáticos que são, o conectivo E e o conectivo OU.

VALOR LÓGICO

O valor lógico é um tipo de dado binário, isto é, assume um valor dentre duas opções: verdadeiro ou falso.

Os valores lógicos são de fato a base de toda a computação, até porque, temos que, o bit está ligado ou o bit está desligado. O valor lógico em sua forma mais primitiva assume o número 1 quando verdadeiro e assume o valor 0 quando falso.

Toda expressão avaliada na computação de maneira geral, resulta num valor lógico, isto é, ou a expressão é verdadeira, ou a expressão é falsa. Como aprenderemos de agora em diante, todas as estruturas da linguagem Python baseiam-se nos 2 valores lógicos possíveis.

O TIPO DE DADO BOOLEANO (bool)

O tipo de dado Booleano, que em Python é representado pela classe bool assume um valor dentre 2 valores constante: True ou False. A palavra Booleano vem do sobrenome do filósofo e matemático George Boole o criado da Álgebra Booleana .

Se formos no IDLE e verificarmos com a instrução type() o tipo dos valores lógicos ou então, o tipo de uma expressão lógica, teremos como resposta o valor <class 'bool'>.

Como podemos ver acima o Python reconhece as 2 constantes como pertencentes ao tipo de dado bool, no caso, as constantes True e False. É importante notar que ambas constantes iniciam com letra maiúscula, do contrário, o Python tratará como sendo uma referência desconhecida.

CONECTIVOS LÓGICOS

As linguagens de programação, utilizam os conectivos lógicos da lógica formal, ou melhor da lógica Aristotélica, na construção de expressões lógicas. Existem 2 conectivos lógicos e, mesmo que não os conheçamos com o nome de conectivos lógicos, utilizamo-os constantemente ao conversarmos ou então, para explicarmos qualquer disciplina a outra pessoa.

Os dois conectivos lógicos são:

Por exemplo, a simples frase A e B são caracteres iguais implica numa expressão lógica e acabamos de representar a mesma textualmente. Porém, a expressão pode ser facilmente escrita matematicamente, ou então, com o uso de uma linguagem de programação.

Por essa razão, devemos olhar para as Linguagens de Programação como sendo, antes de tudo, formas ou estilos de Notação lógica. Como sabemos, existe a notação matemática que possui suas próprias regras e sua própria sintaxe. Existem algumas linguagens de programação que por exemplo, suportam a sintaxe matemática na definição de expressões e na composição de sentenças lógicas.

Por fim, os conectivos lógicos devem ser entendidos como ferramenta de notação utilizada para unir duas ou mais expressões, e como resultado da união, forma-se uma nova expressão.

AVALIAÇÃO DE EXPRESSÕES

A avaliação de expressão em linguagens de programação é, o trabalho que o compilador ou interpretador faz, quando este, através de 2 expressões, avalia se a proposição, isto é, a expressão avaliada é ou não verdadeira.

É importante observar que as expressões, são sempre avaliadas se são verdadeiras e é bom esse entendimento, até porque, podia ser o contrário, e as vezes será, quando assim desejarmos e utilizarmos uma notação especifica para isso.

Então, por padrão, todas as expressão são avaliadas com a pergunta se são ou não verdadeiras.

TABELA DE VALORES LÓGICOS

A tabela de valor lógica é uma tabela que mostra o resultado da avaliação de 2 expressões lógicas. É importante observar que essa tabela NÃO é uma convenção, mas sim, o resultado da dedução lógica e que você pode facilmente deduzi-la.

True E True é True True E False é False False E True é False

True OU False é True False OU True é True True OU True é True False OU False é False

O CONECTIVO DE CONJUNÇÃO E

O conectivo lógico de conjunção E, une a expressão a sua esquerda a expressão a sua direita. Expressões com o uso do conectivo de conjunção originam frases em Português, mais ou menos assim: A é verdadeiro e B é verdadeiro.

Nas situações em que A for verdadeiro e B também, o resultado, segundo a tabela lógica, será também verdadeiro.

No exemplo acima, temos uma expressão lógica composta constituida por 2 expressões lógicas simples e, ligadas pelo conectivo de conjunção.

Primeira expressão simples: (var1 == 0) Segunda expressão simples expressão:(var1 == 0) Conectivo lógico de conjunção: and

Para analisarmos uma expressão lógica composta, precisamos antes, analisar suas expressões lógicas simples.

No trecho de código acima, a primeira sub-expressão, analisas se o valor da variável x é maior do que 0. A variável x está declarada na linha anterior a expressão e inicializada com o valor 1, por isso, a primeira sub-expressão é verdadeira.

A segunda expressão, analisa se o valor da variável x é menor do que 100. O valor da variável x é igual a 1 e, por isso, menor do que 100. Por fim, obtivemos 2 valores lógicos e agora podemos deduzir o resultado lógica de toda expressão e o fazemos no trecho de código a seguir.

No código acima, temos a mesma expressão do exemplo anterior, porém, substituimos as duas expressões lógicas simples por seus respectivos valores lógicos, isto é, o valor decorrente da análise lógica de cada sub-expressão.

A expressão (True) and (True), se comparada com a Tabela Lógica de Valores, tem-se que o valor decorrente dessa segunda análise, será True, até porque, True and True == True.

CONECTIVO DE DISJUNÇÃO OU

O conectivo lógico de disjunção OU liga a expressão a sua esquerda a expressão a sua direita. Expressões com o uso do conectivo de disjunção dão origem a frases em Português mais ou menos assim: A é verdadeiro OU B é verdadeiro.

O operador lógico OU sempre precisará que uma das 2 sub-expressões conectadas sejam verdadeiras para que, a expressão num todo seja verdadeira.

A expressão lógica composta que temos no código acima, será desmembrada como estudado anteriormente, e agora, para que a avaliação seja verdadeira, uma das 2 expressões simples precisam ser verdadeiras.

A primeira expressão (x > 10), a variável``x`` está declarada na linha anterior e inicializada com o valor igual a 1, logo, essa expressão é falsa, até porque, o valor de x não é maior do que 10.

A segunda expressão (x < 100) está perguntando se o valor da variável x é menor do que o número 100. Essa expressão é verdadeira, até porque, o número 1 é menor do que o número 100.

No código a seguir, temos a expressão originada a partir do código anterior.

Agora, temos que o primeiro valor lógico é falso, enquanto o segundo é verdadeiro. Esse valores estão ligados pelo conectivo de disjunção que será verdadeiro caso uma das sub-expressões o seja. Como o segundo valor lógico é verdadeiro, o valor decorrente dessa análise lógica será verdadeiro.

EXPRESSÕES SIMPLES E COMPOSTAS

Os operadores relacionais obtém a relação entre os operandos e, por isso, podemos chamar esse tipo de expressão como sendo, expressões simples.

As expressões compostas, por sua vez, são a união de 2 ou mais expressões simples e, ligadas por algum conectivo lógico. A seguir, temos um exemplo utilizando o conectivo lógico de conjunção que une 2 expressões e dá origem a uma nova expressão lógica.

EXEMPLO 1
isso E isso

EXEMPLO 2
x E y

Em ambos exemplos, estamos unindo 2 membros, mas não estamos perguntando nada. Porém, a frase correta e que é utilizada pela grande maioria das linguagens de programação, senão todas, é a seguinte: A é verdadeiro e B é verdadeiro, logo .... Chamamos isso de expressão lógica ou melhor, expressão lógica composta, até porque, a expressão se origina de duas outras expressões, isto é, a que está ao lado esquerdo do operador relacional e a expressão que está ao seu lado direito.

# data[].attributes.attachment_link.description
Nesta aula estudaremos os operadores lógicos na linguagem Python. Aprenderemos também a definição de valor lógica, a definição de conjunção, disjunção e de sub-expressões lógicas. Os operadores lógicos unem expressões lógicas formando assim, uma nova expressão que é composta por 2 ou mais sub-expressões. O resultado lógico de expressões compostas será a relação entre as sub-expressões.

# data[].attributes.body
Depois de assistir à Aula 09 com o professor e os conteúdos aqui do mural,  participe do desafio! (Disponível de 03/05/2022 a  12/05
/2022)

# data[].attributes.body
Expressões e precedência. Vídeo curto (8 minutos).

# data[].attributes.attachment_link.title
Aula 05 - U1 - Avaliação de expressões numéricas em Python

# data[].attributes.body
Encademento de Comparadores. Vídeo curto (8 minutos).

# data[].attributes.attachment_link.title
Python e Matemática. Coisas Escondidas. Conheça o Encadeamento de Operadores de Comparação.

# data[].attributes.body
Introdução às Funções em Python. Vídeo curto (8 minutos).

# data[].attributes.attachment_link.title
4.6 def - Funções (Parte 1) - Tutorial Python 3 em Português

# data[].attributes.body
Funções com retorno. Vídeo médio (20 minutos).

# data[].attributes.attachment_link.title
Funções (def e return) em Python - Aula 16 (Parte 2)

# data[].attributes.body
Depois de assistir à Aula 10 com o professor e os conteúdos deste mural,  participe do desafio! (Disponível de 13/05/2022 a  23/05/2022)

# data[].attributes.body
Criando módulos em Python. Video curto (6 minutos).

# data[].attributes.attachment_link.title
Curso Python 300 - Aula 34 - Criando módulos

# data[].attributes.body
Introdução à Interface Gráfica com o Tkinter. Vídeo médio (20 minutos).

# data[].attributes.attachment_link.title
Interface Gráfica no Python com Tkinter - Curso de Python #57

# data[].attributes.body
Introdução à Interface Gráfica com o Tkinter - Parte 2. Vídeo médio (18 minutos).

# data[].attributes.attachment_link.title
Tkinter, Entry e Text - Curso de Python #58

# data[].attributes.body
Introdução à Interface Gráfica com o Tkinter - Parte 3. Vídeo médio (14 minutos).

# data[].attributes.attachment_link.title
Tkinter, Button Widget - Curso de Python #59