One place for hosting & domains

      How To Use Loops in Ansible Playbooks



      Part of the Series:
      How To Write Ansible Playbooks

      Ansible is a modern configuration management tool that doesn’t require the use of an agent software on remote nodes, using only SSH and Python to communicate and execute commands on managed servers. This series will walk you through the main Ansible features that you can use to write playbooks for server automation. At the end, we’ll see a practical example of how to create a playbook to automate setting up a remote Nginx web server and deploy a static HTML website to it.

      When automating server setup, sometimes you’ll need to repeat the execution of the same task using different values. For instance, you may need to change permissions of multiple files, or create multiple users. To avoid repeating the task several times in your playbook file, it’s better to use loops instead.

      In programming, a loop allows you to repeat instructions, typically until a certain condition is met. Ansible offers different looping methods, with the loop keyword being the most recommended option for longer term compatibility.

      The following example creates three different files on the /tmp location. It uses the file module within a task that implements a loop using three different values.

      Create a new file called playbook-06.yml in your ansible-practice directory:

      • nano ~/ansible-practice/playbook-06.yml

      Then add the following lines to the new playbook file:

      ~/ansible-practice/playbook-06.yml

      ---
      - hosts: all
        tasks:
          - name: creates users files
            file:
              path: /tmp/ansible-{{ item }}
              state: touch
            loop:
              - sammy
              - erika
              - brian
      

      Save and close the file when you’re done.

      Then, run ansible-playbook with the same connection arguments from the previous examples. Again, we’re using an inventory file named inventory and a user named sammy, but you should change these values accordingly:

      • ansible-playbook -i inventory playbook-06.yml -u sammy

      You’ll get output like this, showing each individual item value that was used within the loop:

      Output

      ... TASK [creates users files] ****************************************************************************** changed: [203.0.113.10] => (item=sammy) changed: [203.0.113.10] => (item=erika) changed: [203.0.113.10] => (item=brian) ...

      For more detailed information on how to use loops when writing Ansible playbooks, please refer to the official documentation.



      Source link

      Como usar as instruções break, continue, e pass ao trabalhar com loops em Python 3


      Introdução

      O uso de loops do tipo “for” e loops do tipo “while” em Python permite que você automatize e repita tarefas de maneira eficiente.

      No entanto, pode acontecer de um fator externo influenciar a maneira como seu programa é executado. Quando isso ocorre, é desejável que seu programa saia de um loop completamente, ignore parte de um loop antes de continuar, ou ignore aquele fator externo. É possível realizar essas ações com as instruções break, continue e pass.

      Instrução break

      Em Python, a instrução break oferece a possibilidade de sair de um loop quando uma condição externa é acionada. A instrução break será colocada dentro do bloco de código abaixo da sua instrução de loop, geralmente após uma instrução condicional if.

      Vamos ver um exemplo que usa a instrução break em um loop do tipo "for":

      number = 0
      
      for number in range(10):
          if number == 5:
              break    # break here
      
          print('Number is ' + str(number))
      
      print('Out of loop')
      
      

      Neste pequeno programa, o number da variável é inicializado em 0. Em seguida, uma instrução for constrói o loop, desde que o number da variável seja menor que 10.

      Dentro do loop for, há uma instrução if que apresenta a condição que se o number da variável for equivalente ao número inteiro 5, então o loop será quebrado.

      Dentro do loop também há uma instrução print() que será executada com cada iteração do loop for até que o loop seja quebrado, uma vez que está localizada após a instrução break.

      Para saber quando estamos fora do loop, incluímos uma instrução final print() fora do loop for.

      Quando executarmos esse código, nosso resultado será o seguinte:

      Output

      Number is 0 Number is 1 Number is 2 Number is 3 Number is 4 Out of loop

      Isso mostra que assim que o number é avaliado como equivalente a 5, o loop é interrompido, uma vez que o programa é orientado a fazer isso com a instrução break.

      A instrução break faz com que um programa seja interrompido para fora de um loop.

      Instrução continue

      A instrução continue dá a opção de ignorar a parte de um loop onde uma condição externa é acionada, mas continuar e completar o resto do loop. Ou seja, a iteração atual do loop será interrompida, mas o programa retornará ao topo do loop.

      A instrução continue ficará dentro do bloco de código abaixo da instrução de loop, geralmente após uma instrução condicional if.

      Usando o mesmo programa de loop for que na seção anterior da Instrução break, usaremos uma instrução continue, em vez de uma instrução break:

      number = 0
      
      for number in range(10):
          if number == 5:
              continue    # continue here
      
          print('Number is ' + str(number))
      
      print('Out of loop')
      
      

      A diferença entre usar a instrução continue, em vez de uma instrução break, é que o nosso código continuará apesar da interrupção quando a variável number for avaliada como equivalente a 5. Vamos ver nosso resultado:

      Output

      Number is 0 Number is 1 Number is 2 Number is 3 Number is 4 Number is 6 Number is 7 Number is 8 Number is 9 Out of loop

      Aqui, Number is 5 nunca ocorre no resultado, mas o loop continua após esse ponto e imprime linhas para os números 6-10 antes de ser finalizado.

      Você pode usar a instrução continue para evitar um código condicional extremamente aninhado, ou para otimizar um loop, eliminando casos que ocorram com frequência e que você gostaria de rejeitar.

      A instrução continue faz com que um programa pule certos fatores que surjam dentro de um loop, mas depois continuem pelo restante do loop.

      Declaração pass

      Quando uma condição externa é acionada, a instrução pass permite lidar com a condição sem que o loop seja impactado; todo o código continuará sendo lido a menos que um break ou outra instrução ocorra.

      Assim como ocorre com outras instruções, a instrução pass ficará dentro do bloco de código abaixo da instrução de loop, normalmente após uma instrução condicional if.

      Usando o mesmo bloco de código anterior, vamos substituir a instrução break ou continue por uma instrução pass:

      number = 0
      
      for number in range(10):
          if number == 5:
              pass    # pass here
      
          print('Number is ' + str(number))
      
      print('Out of loop')
      
      

      A instrução pass que ocorre após a instrução condicional if está dizendo ao programa para continuar executando o loop e ignorar o fato de que a variável number é avaliada como equivalente a 5 durante uma das iterações.

      Vamos executar o programa e verificar o resultado:

      Output

      Number is 0 Number is 1 Number is 2 Number is 3 Number is 4 Number is 5 Number is 6 Number is 7 Number is 8 Number is 9 Out of loop

      Ao usar a instrução pass neste programa, notamos que o programa é executado exatamente como seria se não houvesse nenhuma instrução condicional no programa. A instrução pass diz ao programa para desconsiderar essa condição e continuar executando o programa como sempre.

      A instrução pass pode criar classes mínimas, ou agir como um espaço reservado enquanto estamos trabalhando em novos códigos e pensando em um nível algorítmico antes de construir detalhes.

      Conclusão

      As instruções break, continue e pass em Python permitem que você use loops for e while com maior efetividade em seu código.

      Para trabalhar mais com as instruções break e pass, siga nosso tutorial de projeto “Como criar um Twitterbot com Python 3 e a biblioteca Tweepy.”



      Source link

      Como construir loops for no Go


      Introdução

      Em programação de computadores, um loop é uma estrutura de código que faz um loop para executar repetidamente uma parte de um código, frequentemente até que alguma condição seja alcançada. O uso de loops em programação de computadores permite que você automatize e repita tarefas semelhantes várias vezes. Vamos supor que você tivesse uma lista de arquivos que precisasse processar, ou se quisesse contar o número de linhas em um artigo. Você poderia usar um loop em seu código para resolver esses tipos de problemas.

      Na linguagem Go, um loop for implementa a execução repetida de um código baseado em um contador ou uma variável de loop. Ao contrário do que ocorre com outras linguagens de programação que têm vários constructos de looping como o while, do etc., o go tem somente o loop for. Isso serve para tornar seu código mais claro e mais legível, considerando que você não precisa se preocupar com várias estratégias para chegar no mesmo constructo de looping. Essa legibilidade aprimorada e a redução da carga cognitiva durante o desenvolvimento também tornarão o seu código menos propenso a erros do que com outras linguagens.

      Neste tutorial, você aprenderá como o loop for do Go funciona, incluindo as três grandes variações de sua utilização. Vamos começar mostrando como criar diferentes tipos de loops for, seguido de como fazer o loop através de tipos de dados sequenciais em Go. Vamos terminar explicando como usar os loops aninhados

      Declarando o ForClause e os loops de condição

      Para atender a uma variedade de casos de uso, existem três maneiras diferentes de criar loops for em Go, cada qual com seus próprios recursos. Essas maneiras são para criar um loop for com uma Condition, uma ForClause, ou uma RangeClause. Nesta seção, explicaremos como declarar e usar as variantes ForClause e Condição.

      Vamos ver como podemos usar um loop for com o ForClause primeiro.

      Um ForClause loop é definido como tendo uma instrução inicial, seguida de uma condição e, depois, uma instrução de post. Eles são organizados com a seguinte sintaxe:

      for [ Initial Statement ] ; [ Condition ] ; [ Post Statement ] {
          [Action]
      }
      

      Para explicar o que os componentes anteriores fazem, vejamos um loop for que incrementa por meio de uma gama especificada de valores usando a sintaxe do ForClause:

      for i := 0; i < 5; i++ {
          fmt.Println(i)
      }
      

      Vamos desmembrar esse loop e identificar cada parte.

      A primeira parte do loop é i := 0. Esta é a instrução inicial:

      for i := 0; i < 5; i++ {
          fmt.Println(i)
      }
      

      Essa instrução afirma que estamos declarando uma variável chamada i e definindo o valor inicial para 0.

      Em seguida, temos a condição:

      for i := 0; i < 5; i++ {
          fmt.Println(i)
      }
      

      Nessa condição, afirmamos que enquanto o i for menor do que o valor 5, o loop deve continuar em looping.

      Por fim, temos a instrução post:

      for i := 0; i < 5; i++ {
          fmt.Println(i)
      }
      

      Na instrução post, incrementamos a variável do loop i em um toda vez que uma iteração ocorrer, usando o operador de incremento i++.

      Quando executamos esse programa, o resultado fica parecido com este:

      Output

      0 1 2 3 4

      O loop executou 5 vezes. Inicialmente, ele definiu i para 0 e, depois, verificou se o i era menor do que 5. Como o valor de i era menor que 5, o loop executou e a ação de fmt.Println(i) foi executada. Após o loop terminar, o instrução post i++ foi chamada e o valor i foi incrementado em 1.

      Nota: tenha em mente que, em programação, tendemos a começar no índice 0, o que explica por que, a despeito da impressão de 5 números, eles variam de 0 a 4.

      Não estamos limitados a iniciar no 0 ou concluir em um valor especificado. Podemos atribuir qualquer valor para nossa instrução inicial e parar em qualquer valor em nossa instrução post. Isso nos permite criar qualquer intervalo desejado para fazer o loop:

      for i := 20; i < 25; i++ {
          fmt.Println(i)
      }
      

      Aqui, a iteração vai de 20 (inclusive) até 25 (exclusive), de modo que o resultado fica parecido com este:

      Output

      20 21 22 23 24

      Também podemos usar nossa instrução post para incrementar em diferentes valores. Esse procedimento é parecido com o step de outras linguagens:

      Primeiro, vamos usar uma instrução post com um valor positivo:

      for i := 0; i < 15; i += 3 {
          fmt.Println(i)
      }
      

      Neste caso, o loop for foi configurado para que os números de 0 a 15 sejam impressos, mas a incrementos de 3, de modo a imprimir apenas um número a cada três, desta forma:

      Output

      0 3 6 9 12

      Também podemos usar um valor negativo para que o nosso argumento de instrução post faça a iteração retroativamente. Teremos, porém, que ajustar devidamente nossa instrução inicial e os argumentos de condição:

      for i := 100; i > 0; i -= 10 {
          fmt.Println(i)
      }
      

      Aqui, definimos i para um valor inicial de 100, usamos a condição i < 0 para parar em 0 e a instrução post para diminuir o valor em 10 com o operador -=. O loop começa em 100 e termina em 0, diminuindo o valor em 10 a cada iteração. Podemos ver isso ocorrer no resultado:

      Output

      100 90 80 70 60 50 40 30 20 10

      Também é possível excluir a instrução inicial e a instrução post da sintaxe for e usar apenas a condição. Trata-se de um loop de Condição:

      i := 0
      for i < 5 {
          fmt.Println(i)
          i++
      }
      

      Desta vez, declaramos a variável i separadamente do loop for na linha anterior do código. O loop tem apenas uma cláusula de condição que verifica se o i é menor do que 5. Desde que a condição avalie como true, o loop continuará a iterar.

      Às vezes, você pode não saber o número de iterações que serão necessárias para concluir uma determinada tarefa. Neste caso, é possível omitir todas as instruções e usar a palavra-chave break para sair da execução:

      for {
          if someCondition {
              break
          }
          // do action here
      }
      

      Como exemplo disso, vamos supor que estivéssemos lendo uma estrutura de tamanho indeterminado como a de um buffer e não soubéssemos quando terminaríamos a leitura:

      buffer.go

      package main
      
      import (
          "bytes"
          "fmt"
          "io"
      )
      
      func main() {
          buf := bytes.NewBufferString("onentwonthreenfourn")
      
          for {
              line, err := buf.ReadString('n')
              if err != nil {
                  if err == io.EOF {
      
                      fmt.Print(line)
                      break
                  }
                  fmt.Println(err)
                  break
              }
              fmt.Print(line)
          }
      }
      

      No código anterior, o buf :=bytes.NewBufferString("onentwonthreenfourn") declara um buffer com alguns dados. Como não sabemos quando o buffer irá terminar a leitura, criamos um loop for sem cláusula. Dentro do loop for, usamos line, err := buf.ReadString('n') para ler uma linha do buffer e verificamos se existe um erro ao ler do buffer. Se houver, lidamos com o erro e usamos a palavra-chave break para sair do loop for. Com esses pontos de break, não é necessário incluir uma condição para interromper o loop.

      Nesta seção, aprendemos como declarar um loop do ForClause e a usá-lo para iterar por meio de uma gama conhecida de valores. Também aprendemos a usar um loop de condição para iterar até que uma condição específica seja cumprida. Em seguida, vamos aprender como o RangeClause é usado para iterar através de tipos de dados sequenciais.

      Na linguagem Go, é comum o uso de loops for para iterar sobre os elementos de tipos de dados sequenciais ou dados de coleta sequencial ou tipos de dados de coleta, como fatias, matrizes e strings. Para facilitar esse processo, podemos utilizar um loop for com a sintaxe do RangeClause. Embora você possa fazer loops em tipos de dados sequenciais usando a sintaxe do ForClause, a RangeClause é mais clara e fácil de ler.

      Antes de examinarmos o uso da RangeClause, vejamos como podemos iterar por meio de uma fatia, usando a sintaxe do ForClause:

      main.go

      package main
      
      import "fmt"
      
      func main() {
          sharks := []string{"hammerhead", "great white", "dogfish", "frilled", "bullhead", "requiem"}
      
          for i := 0; i < len(sharks); i++ {
              fmt.Println(sharks[i])
          }
      }
      

      Executar isso dará o seguinte resultado, imprimindo cada um dos elementos da fatia:

      Output

      hammerhead great white dogfish frilled bullhead requiem

      Agora, vamos usar a RangeClause para executar o mesmo conjunto de ações:

      main.go

      package main
      
      import "fmt"
      
      func main() {
          sharks := []string{"hammerhead", "great white", "dogfish", "frilled", "bullhead", "requiem"}
      
          for i, shark := range sharks {
              fmt.Println(i, shark)
          }
      }
      

      Neste caso, estamos imprimindo cada item da lista. Embora tenhamos usado as variáveis i e shark, poderíamos ter chamado as variáveis por qualquer outro nome de variável válido e, ainda assim, obteríamos o mesmo resultado:

      Output

      0 hammerhead 1 great white 2 dogfish 3 frilled 4 bullhead 5 requiem

      Ao usar range em uma fatia, ele irá sempre retornar dois valores. O primeiro valor será o índice em que a iteração atual do loop está e o segundo será o valor naquele índice. Neste caso, para a primeira iteração, o índice era 0, e o valor era hammerhead.

      Às vezes, queremos apenas o valor dentro dos elementos da fatia, não do índice. Se alterarmos o código anterior para imprimir apenas o valor, no entanto, vamos receber um erro de tempo de compilação:

      main.go

      package main
      
      import "fmt"
      
      func main() {
          sharks := []string{"hammerhead", "great white", "dogfish", "frilled", "bullhead", "requiem"}
      
          for i, shark := range sharks {
              fmt.Println(shark)
          }
      }
      

      Output

      src/range-error.go:8:6: i declared and not used

      Como o i foi declarado no loop for, mas nunca foi usado, o compilador responderá com o erro i declared and not used. Este é o mesmo erro que você receberá no Go sempre que for declarar uma variável e não a utilizar.

      Por isso, o Go tem o identificador em branco, que é um sublinhado (_). Em um loop for, é possível utilizar o identificador em branco para ignorar qualquer valor retornado da palavra-chave range. Neste caso, queremos ignorar o índice, que é o primeiro argumento retornado.

      main.go

      package main
      
      import "fmt"
      
      func main() {
          sharks := []string{"hammerhead", "great white", "dogfish", "frilled", "bullhead", "requiem"}
      
          for _, shark := range sharks {
              fmt.Println(shark)
          }
      }
      

      Output

      hammerhead great white dogfish frilled bullhead requiem

      Esse resultado mostra que o loop for iterou por toda a fatia de strings e imprimiu cada item da fatia sem o índice.

      Também é possível usar o range para adicionar itens a uma lista:

      main.go

      package main
      
      import "fmt"
      
      func main() {
          sharks := []string{"hammerhead", "great white", "dogfish", "frilled", "bullhead", "requiem"}
      
          for range sharks {
              sharks = append(sharks, "shark")
          }
      
          fmt.Printf("%qn", sharks)
      }
      

      Output

      ['hammerhead', 'great white', 'dogfish', 'frilled', 'bullhead', 'requiem', 'shark', 'shark', 'shark', 'shark', 'shark', 'shark']

      Aqui, adicionamos uma string com espaço reservado de "shark"para cada item do comprimento da fatia sharks.

      Note que não precisamos usar o identificador em branco _ para ignorar nenhum dos valores retornados do operador range. O Go nos permite omitir toda a parte da instrução range se não precisarmos usar qualquer um do valores retornados.

      Também podemos usar o operador range para preencher valores de uma fatia:

      main.go

      package main
      
      import "fmt"
      
      func main() {
          integers := make([]int, 10)
          fmt.Println(integers)
      
          for i := range integers {
              integers[i] = i
          }
      
          fmt.Println(integers)
      }
      

      Neste exemplo, a fatia integers é inicializada com dez valores em branco, mas o loop for define todos os valores desta forma:

      Output

      [0 0 0 0 0 0 0 0 0 0] [0 1 2 3 4 5 6 7 8 9]

      A primeira vez que imprimimos o valor da fatia integers, vemos todos os zeros. Então, iteramos pro meio de cada índice e definimos o valor para o índice atual. Em seguida, imprimimos o valor de integers uma segunda vez, mostrando que todos eles agora têm um valor de 0 a 9.

      Também podemos usar o operador range para iterar por meio de cada caractere em uma string:

      main.go

      package main
      
      import "fmt"
      
      func main() {
          sammy := "Sammy"
      
          for _, letter := range sammy {
              fmt.Printf("%cn", letter)
          }
      }
      

      Output

      S a m m y

      Ao iterar por um mapa, o range retornará a key (chave) e o** value** (valor):

      main.go

      package main
      
      import "fmt"
      
      func main() {
          sammyShark := map[string]string{"name": "Sammy", "animal": "shark", "color": "blue", "location": "ocean"}
      
          for key, value := range sammyShark {
              fmt.Println(key + ": " + value)
          }
      }
      

      Output

      color: blue location: ocean name: Sammy animal: shark

      Nota: é importante notar que a ordem na qual um mapa retorna é aleatória. Cada vez que você executa esse programa, você pode obter um resultado diferente.

      Agora que aprendemos como iterar em dados sequenciais com loops for do tipo range, vamos ver como usar loops dentro de loops.

      Loops for aninhados

      Assim como acontece em outras linguagens de programação, os loops também podem ser aninhados em Go. Nesting (aninhamento) é quando temos um constructo dentro de outro. Neste caso, um loop aninhado é um loop que ocorre dentro de outro loop. Eles podem ser úteis quando o que se quer é uma ação em loop sendo realizada em cada elemento de um conjunto de dados.

      Os loops aninhados são estruturalmente semelhantes às instruções aninhadas if. Eles são construídos desta forma:

      for {
          [Action]
          for {
              [Action]  
          }
      }
      

      Primeiro, o programa encontra o loop externo, executando sua primeira iteração. Essa primeira iteração aciona o loop interno, o loop aninhado, o qual é executado até sua finalização. Em seguida, o programa retorna para o topo do loop externo, finalizando a segunda iteração e acionando novamente o loop aninhado. Novamente, o loop aninhado executa até sua finalização e o programa retorna para o topo do loop externo até a sequência estar completa ou que uma instrução break ou outra interrompa o processo.

      Vamos implementar um loop for aninhado para analisarmos melhor. Neste exemplo, o loop externo irá iterar por uma fatia de inteiros chamada de numList e o loop interno irá iterar por uma fatia de strings chamada alphaList.

      main.go

      package main
      
      import "fmt"
      
      func main() {
          numList := []int{1, 2, 3}
          alphaList := []string{"a", "b", "c"}
      
          for _, i := range numList {
              fmt.Println(i)
              for _, letter := range alphaList {
                  fmt.Println(letter)
              }
          }
      }
      

      Ao executarmos esse programa, vamos receber o seguinte resultado:

      Output

      1 a b c 2 a b c 3 a b c

      O resultado ilustra que o programa termina a primeira iteração do loop externo imprimindo 1, que, por sua vez, aciona a conclusão do loop interno, imprimindo a, b e c, consecutivamente. Assim que o loop interno for finalizado, o programa retorna para o topo do loop externo, imprime o número 2, e imprime novamente o loop interno em sua totalidade (a, b, c) etc.

      Os loops for aninhados podem ser úteis para iterar através de itens dentro de fatias compostas por fatias. Em uma fatia composta por fatias, se usarmos apenas um loop for, o programa dará como resultado cada lista interna como um item:

      main.go

      package main
      
      import "fmt"
      
      func main() {
          ints := [][]int{
              []int{0, 1, 2},
              []int{-1, -2, -3},
              []int{9, 8, 7},
          }
      
          for _, i := range ints {
              fmt.Println(i)
          }
      }
      

      Output

      [0 1 2] [-1 -2 -3] [9 8 7]

      Para acessar cada item individual das fatias internas, implementaremos um loop for aninhado:

      main.go

      package main
      
      import "fmt"
      
      func main() {
          ints := [][]int{
              []int{0, 1, 2},
              []int{-1, -2, -3},
              []int{9, 8, 7},
          }
      
          for _, i := range ints {
              for _, j := range i {
                  fmt.Println(j)
              }
          }
      }
      

      Output

      0 1 2 -1 -2 -3 9 8 7

      Ao usarmos um loop for aninhado aqui, podemos iterar com os itens individuais contidos nas fatias.

      Conclusão

      Neste tutorial, aprendemos a declarar e usar loops for para resolver tarefas repetitivas no Go. Também aprendemos as três diferentes variações de um loop for e quando usá-las. Para aprender mais sobre os loops for e como controlar o fluxo deles, leia o artigo Usando as instruções break e continue ao trabalhar com loops em Go.



      Source link