Lab4 Igor Almeida

aluno: Igor de Sousa Almeida
ano/sem: 2008/2o.
data do laboratório (num. da semana) : 04/11/2008 (6)

Introdução

Durante esse curso de Orientação a Objetos, foram escolhidas duas linguagens para serem utilizadas, Java, de tipagem estática, e Ruby, de tipagem dinâmica, podendo-se assim compreender as diferenças de programação entre essas diferentes tipagens.
Nesse laboratório, é apresentado um programa com a mesma funcionalidade do realizado no segundo laboratório, entretanto ele foi repassado para a linguagem Ruby, com o objetivo de familiarizar com essa linguagem.

Desenvolvimento

Como pedido no roteiro do laboratório, o código foi dividido entre três arquivos, geral.rb com todas as classes do 2° lab, com excessão do simulador, que ficou em simulador.rb, e dos testes, que ficaram em testes.rb.

Geral.rb

Nesse arquivo, pode-se observar algumas diferenças entre Ruby e Java. Os construtores das classes são alterados por métodos initialize que são invocadas na utilização do "new". Pode-se observar também que não é necessária instanciar classes para lançar excessões. No caso das excessões utilizadas, por serem do tipo RuntimeError, puderam ser apenas lançadas com raise + mensagem da excessão. Não existem classes abstratas em Ruby, entretanto a utilização delas não é necessária, os comportamentos, que antes eram subclasses da classe abstrata Comportamento, agora são classes isoladas sem nenhum parentesco. Isso não afeta a funcionalidade do programa, pois, como a tipagem da linguagem é dinâmica, não é necessária instanciar um objeto de Comportamento para atribuir a sua subclasse concreta.

class Professor
 
   def initialize(queue)
      @queue = queue 
   end
 
   private
   def corrigir_relatorio(rela)
      nota = ( rela.qualidade() + rela.originalidade() + rand(0) )/ 3*10
      #/espaço
      return nota 
   end
 
   public
   def corrigir_relatorios()
      correcao = ""
      rela = @queue.dequeue();
      while(rela != nil)
        nota = corrigir_relatorio(rela).to_s
         correcao = correcao + "\n" + rela.aluno().nome()+ " : " + nota
         rela = @queue.dequeue()
      end
       correcao = "Correcao do professor:\n" + correcao;
       print correcao
   end
end
 
class RelaQueue
 
  def initialize
      @array = []
    end
 
    def queue(rela)
      @array.push(rela)
    end
 
    def dequeue()
      if(@array.nil?) 
        print "Fim dos relatórios!"
        valor = nil 
      else
        valor = @array.shift
      end
      return valor
    end
end
 
class Relatorio
 
   def initialize(qualidade, originalidade, aluno)
    @qualidade = qualidade
    @originalidade = originalidade
    @aluno = aluno
   end
 
   def qualidade()
       return @qualidade
   end
   def originalidade()
       return @originalidade
   end
   def aluno()
       return @aluno
   end
end
 
class Burro  
   @@inteligencia = 0
   @@dedicacao = 0
 
   def initialize(aluno)
        @aluno = aluno
   end
 
   public
   def inteligencia()
        return @@inteligencia
   end
    def dedicacao()
        return @@dedicacao
    end
end
 
class Esforcado  
    @@inteligencia = 0.5
    @@dedicacao = 1
 
    def initialize(aluno)
        @aluno = aluno
    end
 
    public
    def inteligencia()
        return @@inteligencia
    end
    def dedicacao()
        return @@dedicacao
    end
end
 
class Imprevisivel  
 
   def initialize(aluno)
        @aluno = aluno
   end
 
    public 
    def inteligencia()
        return rand(0)
    end
    def dedicacao()
        return rand(0)
    end
end
 
class Pemba  
 
   def initialize(aluno)
        @aluno = aluno
   end
 
    public 
    def inteligencia()
        return rand(0) * 0.5
    end
    def dedicacao()
        return rand(0) * 0.5;
    end
end
 
class SafoPreguicoso   
    @@inteligencia = 1
 
    def initialize(aluno)
      @aluno = aluno
    end
 
    public 
    def inteligencia()
        return @@inteligencia
    end
    def dedicacao()
        return rand(0) * 0.5;
    end
end
 
class Summa  
   @@inteligencia = 1
   @@dedicacao = 1
 
   def initialize(aluno)
        @aluno = aluno
   end
 
    public 
    def inteligencia()
        return @@inteligencia
    end
    def dedicacao()
        return @@dedicacao
    end
end
 
  class Aluno
 
    @@conhecimento = 0
 
    def initialize(nome, queue)
        @nome = nome
        @queue = queue
        @comportamento = Esforcado.new(self)
    end
 
    def faz_e_entrega_relatorio()
        self.conhecimento()
        qualidade = (2 * self.dedicacao() + 1 * @comportamento.inteligencia() ) / 3 
        originalidade = (1 * self.dedicacao() + 2 * @comportamento.inteligencia() ) / 3 
        rela = Relatorio.new(qualidade,originalidade,self)
        @queue.queue(rela)
    end
 
    def conhecimento()
        @@conhecimento = @@conhecimento + 1;
    end
 
    def inteligencia()
        return @comportamento.inteligencia();
    end
 
    def dedicacao()
        return @comportamento.dedicacao();
    end
 
    def nome()
        return @nome;
    end
 
    def comportamento=(comportamento) 
        @comportamento = comportamento
    end
end
 
class AlunoITA < Aluno
 
    def initialize(nome,queue)
      super(nome,queue)
    end
 
    def comportamento=(comportamento)  
      if comportamento.instance_of?(Burro) 
        raise "Um iteano n pode ser burro!"
      end
      super comportamento=(comportamento)
    end
 
end
 
class AlunoUSP < Aluno
 
    def initialize(nome, queue)
        super(nome,queue)
    end
 
    def comportamento=(comportamento) 
        if comportamento.instance_of?(Summa) || comportamento.instance_of?(SafoPreguicoso) 
          raise "Somente um iteano pode ser summa ou safo preguicoso!" 
        end
        super comportamento=(comportamento)
    end
 
end
 
class AlunoUnicamp < Aluno
 
    def initialize(nome, queue)
        super(nome,queue)
    end
 
    def comportamento=(comportamento) 
        if comportamento.instance_of?(Summa) || comportamento.instance_of?(SafoPreguicoso)  
          raise "Somente um iteano pode ser summa ou safo preguicoso!"
        end
      super comportamento=(comportamento)
    end
 
end

Simulador.rb

Algumas modificações foram realizadas na classe simulador, não apenas pelas mudanças de linguagem, mas também para que ela fosse simplificada, principalmente pela subtração da interface gráfica. O tratamento das excessões que em Java era realizado através de "try-catch" agora é feito através de "rescue". Pode-se observar que na definição do comportamento do aluno, qualquer uma das classes Pemba, Esforcado, etc pode ser escolhida, devido a tipagem dinâmica da linguagem.

require 'geral'
 
class Simulador
 
    n = String.new
    while !n.instance_of?(Fixnum) || n < 0
        print "Quantos alunos vc deseja inserir? "
        n = gets()
        n = n.to_i
        if n < 0
            puts "Digite um valor valido"
        end
    end
    queue = RelaQueue.new
    prof = Professor.new(queue)
    arrayalunos = Array.new
    (0..n-1).each do |i|
        erro = true
        print "Digite o nome do aluno: "
        nome = gets()                
        nome = nome.chomp
        origem = String.new
        while !origem.instance_of?(Fixnum) || origem < 0 || origem > 2
            print "Digite a origem do aluno:\nITA(0) \nUSP(1) \nUnicamp(2) "
            origem = gets()
            origem = origem.to_i
            if origem < 0 || origem > 2
              puts "Digite um valor valido"
            end
        end 
        if(origem == 0) 
            arrayalunos[i] = AlunoITA.new(nome,queue) 
        elsif(origem == 1) 
            arrayalunos[i] = AlunoUSP.new(nome,queue) 
        elsif(origem == 2) 
            arrayalunos[i] = AlunoUnicamp.new(nome,queue) 
        end    
        until erro != true                   
            begin
                erro = false
                comportamento = String.new
                while !comportamento.instance_of?(Fixnum) || comportamento < 0 || comportamento > 5
                    print "Digite o comportamento do aluno:\nEsforcado(0) \nPemba(1) \nImprevisivel(2) \nSafo(3) \nBurro(4) \nSumma(5) "
                    comportamento = gets()
                    comportamento = comportamento.to_i
                    if comportamento < 0 || comportamento > 5
                        puts "Digite um valor valido"
                    end
                end     
                if(comportamento == 0) 
                    arrayalunos[i].comportamento=(Esforcado.new(arrayalunos[i]))
                elsif(comportamento == 1) 
                    arrayalunos[i].comportamento=(Pemba.new(arrayalunos[i]))
                elsif(comportamento == 2) 
                    arrayalunos[i].comportamento=(Imprevisivel.new(arrayalunos[i]))
                elsif(comportamento == 3) 
                    arrayalunos[i].comportamento=(SafoPreguicoso.new(arrayalunos[i]))
                elsif(comportamento == 4) 
                    arrayalunos[i].comportamento=(Burro.new(arrayalunos[i]))
                elsif(comportamento == 5) 
                    arrayalunos[i].comportamento=(Summa.new(arrayalunos[i]))
                end
            rescue RuntimeError => e
                print "\n" + e.message + "\n\n"
                erro = true
            end
        end 
 
    end
 
    (0..n-1).each do |i|
        arrayalunos[i].faz_e_entrega_relatorio()
    end
    print "Alunos fazem e entregam relatorios...\n"            
    prof.corrigir_relatorios()
 
end

Simulador

simulador

Testes.rb

Os teste realizados para o 2° foram repassados para Ruby, com excessão do último teste que tratava de genéricos, pois uma linguagem de tipagem dinâmica não necessita da utilização dos mesmos. Os testes mostraram os resultados esperados.

require 'geral' 
require 'test/unit'
 
class TestInteressante < Test::Unit::TestCase
  def test_1
    queue = RelaQueue.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 RuntimeError => e
        print "Não deveria lançar erro!"
    end
 
    #teste de alunoesforcado
    assert_equal(0.5, aluno1.inteligencia(), 0.01)
    assert_equal(1, aluno1.dedicacao(), 0.01)
 
    #teste de alunosafo
    assert_equal(1.0, aluno3.inteligencia(), 0.01)
    assert(aluno3.dedicacao() != aluno3.dedicacao()) #deve ser randomica
    assert(aluno3.dedicacao() < 0.5)
 
    #alunos comecam a fazer os relas
    aluno1.faz_e_entrega_relatorio()
 
    #roubamos o relatório do primeiro aluno para investigá-lo
    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)
 
    #os outros continuam a fazer os relas
    aluno2.faz_e_entrega_relatorio()
    aluno3.faz_e_entrega_relatorio()
    aluno4.faz_e_entrega_relatorio()
 
    #deve exibir a coreção dos relas dos aluno2, aluno3, e aluno4, nesta ordem
    #pois "roubamos" o relatório do aluno1
    prof.corrigir_relatorios()
  end
 
  def test_2
    queue = RelaQueue.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 randomica
    assert(safo.dedicacao() < 0.5) 
 
     #teste de imprevisivel
    assert(imprevisivel.inteligencia() != imprevisivel.inteligencia())   #deve ser randomica
    assert(imprevisivel.inteligencia() < 1.0) 
    assert(imprevisivel.dedicacao() != safo.dedicacao())   #deve ser randomica
    assert(imprevisivel.dedicacao() < 1.0) 
 
     #teste de pemba
    assert(pemba.inteligencia() != pemba.inteligencia())   #deve ser randomica
    assert(pemba.inteligencia() < 0.5) 
    assert(pemba.dedicacao() != pemba.dedicacao())   #deve ser randomica
    assert(pemba.dedicacao() < 0.5) 
  end
 
  def test_3
    queue = RelaQueue.new
    aluno_ita = AlunoITA.new("John Smith", queue) 
    aluno_usp = AlunoUSP.new("Mark Smith", queue) 
    aluno_unicamp = AlunoUnicamp.new("Joseph Smith", queue) 
    begin
        aluno_ita.comportamento=( SafoPreguicoso.new(aluno_ita) ) 
        aluno_ita.comportamento=( Summa.new(aluno_ita) ) 
        aluno_usp.comportamento=( Burro.new(aluno_usp) ) 
        aluno_unicamp.comportamento=( Burro.new(aluno_unicamp) ) 
    rescue RuntimeError => e
        print "Não deveria lançar erro!" 
    end
 
    begin
        aluno_ita.comportamento=( Burro.new(aluno_ita) ) 
        print "Deveria lançar erro!" 
    rescue RuntimeError => e
    end
 
    begin
        aluno_usp.comportamento=( SafoPreguicoso.new(aluno_usp) ) 
        print "Deveria lançar erro!" 
    rescue RuntimeError => e
    end
 
    begin
        aluno_unicamp.comportamento=( Summa.new(aluno_unicamp) ) 
        print "Deveria lançar erro!"
    rescue RuntimeError => e
    end
 
  end
 
  def test_4
 
  end
end

Testes realizados

testes

Conclusão

Esse laboratório serviu principalmente para familiarizar aluno com uma linguagem de tipagem dinâmica (Ruby), suas vantagens e desvantagens em relação as linguagens de tipagem estática. Foi observado que esse tipo de linguagem possibilita uma maior liberdade ao usuário no momento da programação, entretanto também possui as suas desvantagens, como, por exemplo, o fato de não ser C-like e, portanto, de sintaxe mais estranha para a maioria dos programadores menos experientes.

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