Lab4 Rafael Siqueira

aluno: Rafael Siqueira
ano/sem: 2008/2o.
data do laboratório (num. da semana) : 06/11/2008 (6)

Introdução

Com a realização desse laboratório, tivemos o primeiro contato programando na linguagem Ruby. Basicamente, portou-se o laboratório 2, inicialmente desenvolvido em Java, para o Ruby, sem nenhuma alteração significativa no funcionamento do programa, apenas utilizando as vantagens oferecidas pela nova linguagem para deixar o código mais enxuto e de mais fácil entendimento.

Desenvolvimento

Para a realização do laboratório, dividiu-se o código em três arquivos: um para as classes, um para os testes, e um para o simulador. Segue abaixo o código completo:

classes.rb

class Aluno
  #Construtor  
  def initialize (nome,queue)
    String @nome = nome
    @queue = queue
    @comportamento = Esforcado.new(self)  
    @conhecimento = 0
  end
 
  attr_accessor :comportamento
  attr_accessor :nome
  attr_accessor :queue
 
  #Método que faz o relatório do aluno dependendo das características do seu comportamento e o coloca na pilha de relatórios
  def fazEEntregaRelatorio
    qualidade = (2*dedicacao+1*inteligencia)/3
    originalidade =(1*dedicacao+2*inteligencia)/3
    rela = Relatorio.new(qualidade,originalidade,self)
    @queue.queue(rela)
    @conhecimento+=1
  end  
 
  def inteligencia
    return @comportamento.inteligencia
  end
 
    def dedicacao
    return @comportamento.dedicacao
  end
end
 
class AlunoITA < Aluno
  #Construtor
  def initialize (nome,queue)
    super(nome,queue)
  end
 
  #Tratamento das restrições de comportamento que o aluno do ITA deve ter (ele não pode ser burro) através do uso de exceções
  def comportamento=(comportamento)
    if(comportamento.class==Burro)
      raise "Alunos do ITA nao podem ser burros"
    else
      @comportamento=comportamento
    end
  end
end
 
class AlunoUSP < Aluno
  #Construtor
  def initialize(nome,queue)
    super(nome,queue)
  end
 
  #Tratamento das restrições de comportamento que o aluno do ITA deve ter, ele não pode ser burro, através do uso de exceções
  def comportamento=(comportamento)
    if(comportamento.class==Summa || comportamento.class==SafoPreguicoso)
      raise "Alunos da USP nao podem ser safos e preguicosos nem summa"
    else
      @comportamento=comportamento
    end
  end
end
 
class AlunoUnicamp < Aluno
  #Construtor
  def initialize(nome,queue)
    super(nome,queue)
  end
 
  #Tratamento das restrições de comportamento que o aluno do ITA deve ter, ele não pode ser burro, através do uso de exceções
  def comportamento=(comportamento)
    if(comportamento.class==Summa || comportamento.class==SafoPreguicoso)
      raise "Alunos da Unicamp nao podem ser safos e preguicosos nem summa"
    else
      @comportamento=comportamento
    end
  end
end
 
class SafoPreguicoso
  #Construtor
  def initialize(aluno)
    @aluno=aluno
    @inteligencia=1
    @dedicacao
  end
 
  attr_reader :inteligencia
 
  def dedicacao
    @dedicacao=rand*0.5
  end
end
 
class Burro
  #Construtor
  def initialize(aluno)
    @aluno=aluno
    @inteligencia=0
    @dedicacao=0
  end
 
  attr_reader :inteligencia
  attr_reader :dedicacao
end
 
class Summa
  #Construtor
  def initialize(aluno)
    @inteligencia=1
    @dedicacao=1
    @aluno=aluno
  end
 
  attr_reader :inteligencia
  attr_reader :dedicacao
end
 
class Esforcado
  #Construtor
  def initialize(aluno)
    @aluno=aluno
    @dedicacao=1
    @inteligencia=0.5
  end
 
  attr_reader :dedicacao
  attr_reader :inteligencia
end
 
class Imprevisivel
  #Construtor
  def initialize(aluno)
    @aluno=aluno
  end
 
  def dedicacao
    @dedicacao=rand
  end
 
  def inteligencia
    @inteligencia=rand
  end
end
 
class Pemba
  #Construtor
  def initialize(aluno)
    @aluno=aluno  
  end
 
  def dedicacao
   @dedicacao=rand*0.5
  end
 
  def inteligencia
    @inteligencia=rand*0.5
  end
end
 
class Queue
  #Estado inicial - fila vazia
  def initialize
    @array = []
    @inicio = 0
    @fim = 0 
  end
 
  def queue(obj)
    @array.push(obj)
    @fim = (@fim+1)%10 
  end
 
  def dequeue
    if(@inicio == @fim)
      return nil
    else
      @inicio = (@inicio+1)%10
      return @array.shift
    end  
  end  
end
 
class Professor
  #Construtor
  def initialize (queue)
    @queue=queue
  end
 
  #Corrige um relatorio e retorna a nota do aluno no mesmo
  def corrigirRelatorio(rela)
    nota = (rela.originalidade+rela.qualidade+rand)/3*10
    return nota
  end
 
  #Método que faz com que todos os relatórios sejam tirados da fila, sejam corrigidos e tenham suas notas impressas na tela
  def corrigirRelatorios
    rela = @queue.dequeue
    while(rela!=nil)
      puts("#{rela.aluno.nome} #{corrigirRelatorio(rela)}")
      rela = @queue.dequeue
    end  
  end 
end
 
class Relatorio  
  #Construtor
  def initialize (qualidade,originalidade,aluno)
    @qualidade = qualidade
    @originalidade = originalidade
    @aluno = aluno
  end 
 
  attr_reader :qualidade
  attr_reader :originalidade
  attr_reader :aluno
end

testes.rb

require 'classes'
require 'test/unit'
 
class Teste < Test::Unit::TestCase
  def testFuncionaComoOLab1()
    queue = Queue.new
    prof = Professor.new(queue)
    aluno1 = Aluno.new("John Smith",queue)
    aluno2 = Aluno.new("Mark Smith",queue)
    aluno3 = Aluno.new("Joseph Smith",queue)
    aluno4 = Aluno.new("Robert Smith",queue)
    begin  
      aluno3.comportamento=SafoPreguicoso.new(aluno3)
      aluno4.comportamento=SafoPreguicoso.new(aluno4)
    rescue Exception => e
      fail("Nao deveria lancar erro!")
    end
 
    #Teste de Aluno Esforçado
    assert_equal(0.5,aluno1.inteligencia,0.01)
    assert_equal(1,aluno1.dedicacao,0.01)
 
    #Teste de Aluno Safo
    assert_equal(1.0,aluno3.inteligencia,0.01)
    assert(aluno3.dedicacao<0.5)
    assert(aluno3.dedicacao != aluno3.dedicacao)
 
    aluno1.fazEEntregaRelatorio()
 
    rela1=queue.dequeue()
    assert_equal(aluno1,rela1.aluno)
    assert(rela1.aluno.nome=="John Smith")
    assert(rela1.qualidade<0.9)
    assert(rela1.qualidade>0.8)
    assert(rela1.originalidade<0.7)
    assert(rela1.originalidade>0.6)
 
    aluno2.fazEEntregaRelatorio()
    aluno3.fazEEntregaRelatorio()
    aluno4.fazEEntregaRelatorio()
 
    prof.corrigirRelatorios()   
  end
 
  def testOsComportamentosFuncionamComoEspecificado()
    queue = Queue.new
    aluno1 = Aluno.new("John",queue)
    summa = Summa.new(aluno1)
    pemba = Pemba.new(aluno1)
    imprevisivel = Imprevisivel.new(aluno1)
    safo = SafoPreguicoso.new(aluno1)
    esforcado = Esforcado.new(aluno1)
    burro = Burro.new(aluno1)
 
    #Teste de Esforcado
    assert_equal(0.5,esforcado.inteligencia,0.01)
    assert_equal(1,esforcado.dedicacao,0.01)
 
    #Teste de Burro
    assert_equal(0.0,burro.inteligencia,0.01)
    assert_equal(0.0,burro.dedicacao,0.01)
 
    #Teste de Summa
    assert_equal(1.0,summa.inteligencia,0.01)
    assert_equal(1.0,summa.dedicacao,0.01)
 
  #Teste de Safo
  assert_equal(1.0,safo.inteligencia, 0.01);
  assert(safo.dedicacao != safo.dedicacao) #Deve ser randômica
  assert(safo.dedicacao < 0.5)
 
  #Teste de Imprevisivel
  assert(imprevisivel.inteligencia != imprevisivel.inteligencia) #Deve ser randômica
  assert(imprevisivel.inteligencia < 1.0)
  assert(imprevisivel.dedicacao != imprevisivel.dedicacao) #Deve ser randômica
  assert(imprevisivel.dedicacao < 1.0)
 
  #Teste de Pemba
  assert(pemba.inteligencia != pemba.inteligencia) #Deve ser randômica
  assert(pemba.inteligencia < 0.5)
  assert(pemba.dedicacao != pemba.dedicacao) #Deve ser randômica
  assert(pemba.dedicacao < 0.5)
  end
 
  def testAsSubClassesDeAlunoTemRestricoes()
    queue = Queue.new
    alunoITA = AlunoITA.new("John Smith", queue)
    alunoUSP = AlunoUSP.new("Mark Smith", queue)
    alunoUnicamp = AlunoUnicamp.new("Joseph Smith", queue)
    begin
    alunoITA.comportamento=SafoPreguicoso.new(alunoITA)
    alunoITA.comportamento=Summa.new(alunoITA) 
    alunoUSP.comportamento=Burro.new(alunoUSP) 
    alunoUnicamp.comportamento=Burro.new(alunoUnicamp) 
    rescue 
      fail("Nao deveria lancar erro!")
    end
 
    begin
    alunoITA.comportamento=Burro.new(alunoITA) 
    fail("Deveria lancar erro!")
    rescue Exception => e
    end
 
    begin
    alunoUSP.comportamento=SafoPreguicoso.new(alunoUSP) 
    fail("Deveria lancar erro!")
    rescue Exception => e
    end
 
    begin
    alunoUnicamp.comportamento=Summa.new(alunoUnicamp) 
    fail("Deveria lancar erro!")
    rescue Exception => e
    end
  end
end

simulador.rb

require 'classes'
 
class Simulador
 
  def main
    #Criacao dos alunos
    begin
      puts("Quantos alunos deseja criar?")
      string = gets()
      num = string.to_i
      puts("Digite um numero valido") if (num<=0)
    end while (num<=0)
    aluno = []
    queue = Queue.new
 
    #Definicao do nome, da universidade e do comportamento dos alunos
    i=1
    while i<=num
      puts("Digite o nome do aluno #{i}: ")
      nome = gets()
      puts("Qual a universidade do aluno #{nome}")
      puts("1 - ITA")
      puts("2 - USP")
      puts("3 - Unicamp")
      begin
        puts("Digite a universidade: ")
        univ = gets()
        uni = univ.to_i
        puts("Digite um numero valido!") if (uni>3 || uni<1)
      end while (uni>3 || uni<1)
      if(uni==1) 
        aluno[i] = AlunoITA.new(nome,queue)
      elsif(uni == 2) 
        aluno[i] = AlunoUSP.new(nome,queue)
      else 
        aluno[i] = AlunoUnicamp.new(nome,queue)
      end
      puts("Qual o comportamento do aluno #{nome}")
      puts("1 - Safo & Preguicoso")
      puts("2 - Esforcado")
      puts("3 - Summa")
      puts("4 - Imprevisivel")
      puts("5 - Pemba")
      puts("6 - Burro")
      #Tratamento das exceções para os comportamentos dos alunos dependendo de sua universidade
      begin
        exc = 0
        puts("Digite o comportamento: ")
        compo = gets()
        comp = compo.to_i
        if(comp == 1)
          if (uni!=1)
            #Alunos da USP ou da Unicamp não podem ser safos e preguiçosos
            begin
              aluno[i].comportamento=SafoPreguicoso.new(aluno[i])
              rescue
                puts("Alunos que nao sao do ITA nao podem ser safos e preguicosos!")
                puts("Digite um comportamento valido")
                exc = 1
            end
          else
            aluno[i].comportamento=SafoPreguicoso.new(aluno[i])
          end
        elsif(comp == 2)
          aluno[i].comportamento=Esforcado.new(aluno[i])
        elsif(comp == 3)
            if (uni!=1)
              #Alunos da USP ou da Unicamp nao podem ser summa
              begin
                aluno[i].comportamento=Summa.new(aluno[i])
                rescue
                  puts("Alunos da USP ou da Unicamp nao podem ser summa")
                  puts("Digite um comportamento valido!")
                  exc = 1
              end
            else
              aluno[i].comportamento=Summa.new(aluno[i])
            end
          elsif(comp == 4)
            aluno[i].comportamento=Imprevisivel.new(aluno[i])
          elsif(comp == 5)
            aluno[i].comportamento=Pemba.new(aluno[i])
          elsif(comp == 6)
            if(uni == 1)
              #Alunos do ITA nao podem ser burros
              begin
                aluno[i].comportamento=Burro.new(aluno[i])
                rescue
                  puts("Alunos do ITA nao pode sem burros")
                  puts("Digite um comportamento valido!")
                  exc = 1
              end
            else
              aluno[i].comportamento=Burro.new(aluno[i])
            end
          end
        puts("Digite um comportamento valido!") if (comp>6 || comp<1)
      end while ((comp>6 || comp<1) || exc == 1)
    i=i+1
    end
    #Criacao do professor
    professor = Professor.new(queue)
    #Alunos fazem e entregam relatorios
    i=1
    while i<=num
      aluno[i].fazEEntregaRelatorio()
      i=i+1
    end
    puts("Os alunos fizeram e entregaram seus relatorios")
    puts("O professor corrigiu os relatorios, as notas seguem abaixo")
    #Professor corrige os relatorios e imprime suas notas
    professor.corrigirRelatorios()
  end
 
  sim = Simulador.new
  sim.main
end

Gostaria de ressaltar alguns pontos interessantes da linguagem que foram descobertos durante a elaboração do laboratório. O fato de Ruby ser dinâmico ajuda bastante, uma vez que não existem preocupações quanto a declaração de variáveis e afins. Com isso, a liberdade de se escrever o código é tremenda, não havendo preocupações pífias com relação a formalidades (como utilização mandatória de ponto e vírgula, de parênteses, de chaves). Quase nada é mandatório, há infinitas possibilidades para se realizar a mesma coisa, basta escolher um caminho. Muito interessante também são os métodos já prontos para diversas classes da biblioteca (como Array e String). Com eles, a classe Queue é facilitada tremendamente, já existem os métodos empilhar e desempilhar basicamente, bastou chamá-los. Muito mais podia ser explorado com relação às vantagens da linguagem, mas como era um primeiro contato, fiquei meio receoso de mudar bastante o código com a finalidade de faciltá-lo e acabar complicando-o ou mesmo comprometendo seu funcionamento.

Abaixo seguem o resultado dos testes e também um exemplo do funcionamento do simulador:

fig1.JPG

Figura 1 - Resultado dos testes

fig2.JPG

Figura 2 - Funcionamento do simulador

Conclusão

O laboratório foi de extrema importância para o aprendizado da linguagem Ruby, uma vez que apenas se aprende realmente a programar, programando. As aulas introduzem os assuntos mas o aprendizado mesmo ocorre na hora de fazer os laboratórios. Gostei da idéia do laboratório de focar simplesmente na linguagem. O objetivo era aprender a linguagem e ele foi alcançado. Se houvesse também um desafio de desenvolvimento incluído, poderia-se ter uma dificuldade desnecessária acompanhando esse aprendizado de linguagem, que é algo gradual e contínuo.

Add a New Comment
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License