Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

Extração de função

Desenvolvi um código simples para tentar entender melhor o processo de extração de função, abaixo está o código inicial:


#dado_publico3.rb
system "cls"
puts "Qual o seu nome?"
nome = gets.chomp

puts nome.upcase + " quantos anos você tem?"
idade = gets.chomp

puts "\n" + "seu nome foi armazenado".upcase
puts nome.upcase + " teste concluído."

if idade.to_i<18
  puts nome.upcase + " que pena você não tem idade para participar do jogo..."
end

if idade.to_i >= 18
  puts "\n" + nome.upcase + " gostaria de participar do jogo de matemática? (sim/nao)"
  confirma = gets.chomp
  if confirma.downcase =="sim"
    puts "\n" + nome.upcase + " vamos testar seu conhecimento de matemática, começaremos com algo simples"
    limite = 3
    for tentativa in 1..limite.to_i
      puts "Qual o resultado da equação x = 9 +8"
      resultado = gets.chomp   
      if resultado.to_i == 17
        puts "Você acertou!!!"
        break
      else
         if tentativa == limite
          puts "\n" + nome.upcase + " você precisa estudar mais e tentar novamente."
          break
        end
        resta = limite-tentativa
        puts "Você ainda tem " + resta.to_s + " tentativas"
      end
   end  
  else
    puts "\n" + "Ok " + nome.upcase + " , até a próxima oportunidade..." 
  end
 end

a execução deste código está ilustrado abaixo:

Qual o seu nome?
ana
ANA quantos anos você tem?
21

SEU NOME FOI ARMAZENADO
ANA teste concluído.

ANA gostaria de participar do jogo de matemática? (sim/nao)
sim

ANA vamos testar seu conhecimento de matemática, começaremos com algo simples
Qual o resultado da equação x = 9 +8
12
Você ainda tem 2 tentativas
Qual o resultado da equação x = 9 +8
13
Você ainda tem 1 tentativas
Qual o resultado da equação x = 9 +8
17
Você acertou!!!
ou
C:\ruby21\programas>ruby dado_privado3c2.rb
Qual o seu nome?
ana
Quantos anos você tem?
12

SEUS DADOS FORAM ARMAZENADOS
ANA você tem 12 anos de idade. TESTE CONCLUíDO.

ANA que pena você não tem idade para participar do jogo...
ou
C:\ruby21\programas>ruby dado_privado3c2.rb
Qual o seu nome?
ana
Quantos anos você tem?
21

SEUS DADOS FORAM ARMAZENADOS
ANA você tem 21 anos de idade. TESTE CONCLUíDO.

ANA gostaria de participar do jogo de matemática? (sim/nao)
nao

Ok ANA , até a próxima oportunidade...

C:\ruby21\programas>

O novo código tentando dividir o código original ficou da seguinte forma:


def pegar_nome
  puts "Qual o seu nome?"
  dado1 = gets.chomp
  dado1
end

def pegar_idade
  puts "Quantos anos você tem?"
  dado2 = gets.chomp
  dado2
end

def imprimir_dados(nome,idade)
  puts "\n" + "seus dados foram armazenados".upcase
  puts nome.upcase + " você tem " + idade.to_s + " anos de idade." + " teste concluído.".upcase
end

def teste_de_matematica
  puts "Qual o resultado da equação x = 9 +8"
  soma = gets.chomp
  soma
end

def menor_idade(nome,idade)
    menor = idade.to_i<18
    if menor
      puts "\n" + nome.upcase + " que pena você não tem idade para participar do jogo..."
      return true
    end
end

def verificar_se_acertou(nome,acertou,tentativa,limite)
    if acertou==17
       puts "Você acertou!!!"
       return true
    else
        if tentativa == limite
          puts "\n" + nome.upcase + " você precisa estudar mais e tentar novamente."
          return false
        end
       resta = limite-tentativa
       puts "Você ainda tem " + resta.to_s + " tentativas"
    end
end

nome = pegar_nome
idade = pegar_idade.to_i
imprimir_dados(nome,idade)
menor_idade(nome,idade)
if idade.to_i >= 18
    puts "\n" + nome.upcase + " gostaria de participar do jogo de matemática? (sim/nao)"
    confirma = gets.chomp
    if confirma.downcase =="sim"
       puts "\n" + nome.upcase + " vamos testar seu conhecimento de matemática, começaremos com algo simples"
       limite = 3
      for tentativa in 1..limite.to_i
          acertou = teste_de_matematica.to_i
           break if verificar_se_acertou(nome,acertou,tentativa,limite)
       end  
    else
      puts "\n" + "Ok " + nome.upcase + " , até a próxima oportunidade..." 
    end
  end

Este novo código comporta-se como o original, as minhas questões são: 1 - como posso dividir em funções os comandos abaixo do 'menor_idade(nome,idade)', estou a alguns dias tentando solucionar este problema...e2 - ficou mais fácil compreender o que este novo código faz do que o anterior? grato por sua atençãoattEduardo

6 respostas

Fala Eduardo tudo certo ?

Primeiro parabéns pelo código separado em funções, ficou bem legal !!

Algumas considerações:

A função já retorna a última instrução então não precisamos retornar a variável novamente. A não ser que tivessemos mais intruções dentro da função, no nosso caso poderia ser:

def pegar_nome
  puts "Qual o seu nome?"
  dado1 = gets.chomp
end

Outra coisa é tentar dar nomes para as variáveis que significam alguma coisa, se outra pessoa for ver seu código, pode não ficar claro que dado1 é o nome do jogador. A variável poderia ser somente nome por exemplo.

É que você passa a função pega_idade para uma variável e converte para inteiro, podemos fazer isso dentro da função já

def pegar_idade
  puts "Quantos anos você tem?"
  dado2 = gets.chomp.to_i
end

Você pode fazer a validação de maior de 18 dentro da função que verifica se a pessoa é menor de 18, ai ficaria uma função só.

Pode fazer outra função para englobar as tentativas de erro, algo como:

def tentativas
  limite = 3
      for tentativa in 1..limite.to_i
          acertou = teste_de_matematica.to_i
          break if verificar_se_acertou(pegar_nome,acertou,tentativa,limite)
      end  
      puts "\n" + "Ok " + pegar_nome.upcase + " , até a próxima oportunidade..." 
end

Boa tarde Felipe, Obrigado pelas dicas, agora percebi que estava sendo redundante e vou me corrigir. Fiz as correções e o código ficou assim:


def pegar_nome
  puts "Qual o seu nome?"
  informar_nome = gets.chomp
end

def pegar_idade
  puts "Quantos anos você tem?"
  informar_idade = gets.chomp.to_i
end

def imprimir_dados(nome,idade)
  puts "\n" + "seus dados foram armazenados".upcase
  puts nome.upcase + " você tem " + idade.to_s + " anos de idade." + " teste concluído.".upcase
end

def verificar_idade(nome,idade)
    menor = idade<18
    if menor
      puts "\n" + nome.upcase + " que pena você não tem idade para participar do jogo..."
      return true
    else
      puts "\n" + nome.upcase + " gostaria de participar do jogo de matemática? (sim/nao)"
      confirma = gets.chomp
       if confirma == "nao"
         puts "\n" + "Ok " + nome.upcase + " , até a próxima oportunidade..." 
         return false
       else
         puts "\n" + nome.upcase + " vamos testar seu conhecimento de matemática, começaremos com algo simples"
         return false
       end
   end
 confirma.downcase
end

def teste_de_matematica
  puts "Qual o resultado da equação x = 9 +8"
  soma = gets.chomp.to_i
end

def verificar_se_acertou(nome,acertou,tentativa,limite)
    if acertou==17
       puts "Você acertou!!!"
       return true
    else
        if tentativa == limite
          puts "\n" + nome.upcase + " você precisa estudar mais e tentar novamente."
          return false
        end
       resta = limite-tentativa
       puts "Você ainda tem " + resta.to_s + " tentativas"
    end
end

nome = pegar_nome
idade = pegar_idade
imprimir_dados(nome,idade)
verificar_idade(nome,idade)
   if idade >= 18
      limite = 3
      for tentativa in 1..limite.to_i
         acertou = teste_de_matematica
           if verificar_se_acertou(nome,acertou,tentativa,limite)
             break
           end
       end
    end       

Além das alterações sugeridas, precisei adicionar o comando 'if idade >= 18' para impedir que os menores de 18 anos tivessem acesso ao jogo, sem este comando, mesmo os menores de idade participavam do jogo. Neste jogo o código pode se comportar de 3 formas: 1o - o usuário não tem idade para participar, e assim é impresso na tela uma mensagem e o código é interrompido; 2o - o usuário tem idade mas não tem interesse em participar do jogo, assim é impresso uma mensagem e o código é interrompido; 3o - o usuário tem idade e interesse em participar do jogo. Quando acerta, o código imprime a mensagem "acertou" e interrompe o código, se errar o código dá 3 chances para o usuário acertar.O 1o e o 3o casos ocorrem corretamente entretanto, o 2o ocorre da seguinte forma:


C:\ruby21\programas>ruby dado_privado3c3.rb
Qual o seu nome?
ana
Quantos anos você tem?
21

SEUS DADOS FORAM ARMAZENADOS
ANA você tem 21 anos de idade. TESTE CONCLUíDO.

ANA gostaria de participar do jogo de matemática? (sim/nao)
nao

Ok ANA , até a próxima oportunidade...
Qual o resultado da equação x = 9 +8
11
Você ainda tem 2 tentativas
Qual o resultado da equação x = 9 +8
12
Você ainda tem 1 tentativas
Qual o resultado da equação x = 9 +8
17
Você acertou!!!

Conforme pode observar, o usuário não estava interessando em participar do jogo. O primeira ação está correto, ou seja o código emite uma mensagem de despedida, mas no lugar de interromper, ele dá prosseguimento ao código que é solucionar a equação. Tentei criar uma variável 'confirma' associado à função 'verifica_idade' e assim como criei o 'if idade >=18' também criei 'if confirma =="sim"', para que o jogo só prosseguisse quando o jogador tivesse idade maior ou igual a 18 e desejasse participar, mas isso não funcionou.

nome = pegar_nome
idade = pegar_idade
imprimir_dados(nome,idade)
aceita = verificar_idade(nome,idade)
   if idade >= 18
      if aceita == "sim"
      limite = 3
      for tentativa in 1..limite.to_i
         acertou = teste_de_matematica
          if verificar_se_acertou(nome,acertou,tentativa,limite)
             break
           end
       end
     end
    end       

Não estou conseguindo achar o erro. Peço desculpas pelo transtorno, o problema desta vez deve ser pequeno, mas são este pequenos problemas que nos consomem tempo e nos deixam meio transtornados.Para desenvolver o código sem dividir em funções levei 1 hora, mas essa tentativa de dividir em funções está sendo bem complexo, estou levando dias é assim mesmo? Tem como ser de outra forma?

solução!

Uma solução é retirar esse trecho de código fora das funções e colocar dentro da função verifica_idade ex:

def verificar_idade(nome,idade)
      menor = idade<18
      if menor
        puts "\n" + nome.upcase + " que pena você não tem idade para participar do jogo..."
        return true
      else
        puts "\n" + nome.upcase + " gostaria de participar do jogo de matemática? (sim/nao)"
        confirma = gets.chomp
         if confirma == "nao"
           puts "\n" + "Ok " + nome.upcase + " , até a próxima oportunidade..." 
           return false
         else
           puts "\n" + nome.upcase + " vamos testar seu conhecimento de matemática, começaremos com algo simples"
           if idade >= 18
            limite = 3
            for tentativa in 1..limite.to_i
               acertou = teste_de_matematica
                 if verificar_se_acertou(nome,acertou,tentativa,limite)
                   break
                 end
             end
          end  
         end
     end

Com relação aprendizado cada um tem o seu tempo para aprender, você está indo muito bem.

Tente fazer primeiro sem funções e depois vai colocando dentro de funções apenas trechos de código pequenos.

Com o passar do tempo do curso você vai lapidando seu raciocínio com relação as funções não se preocupe.

Felipe, mais uma vez obrigado pela ajuda. Finalmente o código funcionou conforme de forma semelhante ao da forma estendida.Confesso que até pensei em fazer algo parecido com a sua sugestão, mas o que eu não sabia é que dava para invocar uma função dentro de outra , sabia que era possível acessar o valor retornado de uma função em outra, isso procurei explorar bastante. O código apresentado pelo Guilherme, o 'maior_ou_menor.rb' de fato algumas possibilidades, mas o código dele funcionava invocando uma função seguida de outra , não uma dentro da outra.Uma outra questão, a função 'verificar_idade' não ficou longa, você acha que valeria a pena tentar dividir em trechos menores ou está bom o suficiente? Muito obrigado pela sua paciência e atenção.

Oi Eduardo

Eu não me preocuparia com tamanho da função por enquanto, com o tempo você mesmo vai perceber maneiras de diminuir as funções

Você está indo muito bem =)

não deixe de postar dúvidas

Obrigado.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software