Método Para Traduzir String

maio, 2 - 2008

Sempre pensei em um método que traduzisse uma String, na linguagem mesmo, encapsulado, sem precisar de classes de terceiros, etc. Há algum tempo atrás resolvi fazê-lo em Ruby e ficou guardado um bom tempo, até eu realmente precisar usá-lo, aproveito e mostro a vocês.

require "net/http";
require "uri";
require "hpricot";

class String
  
  def translate(from, to, opts={})
    params = {
      "text" => self, 
      "langpair" => "#{from}|#{to}", 
      "ie" => opts.delete(:encode) || "UTF-8", 
      "hl" => "pt-BR"
    }.merge(opts);
    text = Net::HTTP.post_form(URI.parse("http://translate.google.com/translate_t"), params).body;
    Hpricot(text).search("#result_box").inner_html;
  end
  
end

"A simple text to be translated".translate(:en, :pt);  #=> "Um simples texto a ser traduzido"

Ele faz uma consulta ao Google Tradutor e retorna o resultado traduzido. O primeiro parâmetro é a abreviação da língua na qual a String foi escrita e o segundo a língua para qual ela será traduzida, há também um terceiro, um hash com dados a serem enviados via POST. Ele usa a biblioteca Hpricot para buscar o trecho correspondente à tradução no documento HTML, poderia ser feito com expressões regulares, mas ficaria feio.


RadRails 1.0 Lançado

março, 17 - 2008

Há algum tempo foi lançada a versão 1.0 do RadRails, que agora faz parte do projeto Aptana. A vantagem é que o Aptana já era uma ótima IDE para XHTML, CSS e Javascript, depois que integrou o RadRails e suporte a PHP ficou melhor ainda. Nessa nova versão do RadRails vieram algumas melhorias e acertos, além de uma interface um pouco melhorada. Algumas das novas funcionalidades:

  • Suporte ao Rails 2.0
  • Suporte a JRuby nativo (viva!)
  • Aba de vizualização RDoc
  • Code Completion agora sugere argumentos de métodos

O suporte, via IDE, dos servidores foi melhorado, agora eles iniciam automáticamente com a criação do projeto. Falando nisso, a tela de criação de projeto melhorou, foram adicionadas novas opções muito úteis como a versão do Rails que vai ser usada no projeto, o tipo de banco de dados (fim do sqlite como default), e os servidores que serão criados. Novo Rails Shell, para quem prefere usar a linha de comando às janelas da IDE. Vale a pena conferir!

Para instalar/atualizar o RadRails no Aptana: Help > Software Updates > Find and Install… > Search for new features to install > Next > Selecione “Aptana: RadRails Development Enviroment” > Finish


Contando Troco No Ruby Quiz

janeiro, 30 - 2008

Vindo do blog Nome Do Jogo, fiquei sabendo do novo desafio do Ruby Quiz. Há um tempo atrás acompanhava cada novo desafio, alguns que eu achava interessante, tentava resolvê-los, mas nunca cheguei a enviar a solução pra lá. Mas esse desafio é simples e bastante divertido.

O desafio é criar um método que recebe dois argumentos, um deles é um valor que deve ser dividido em moedas fornecidas no segundo argumento, o método tem que retornar um array com a menor combinação possível de moedas. Imagine ter que dar 37 centavos em moedas de 25, 10, 5 e 1? O certo seria receber uma de 25, uma de 10 e duas de 1, veja o código pra entender melhor:

irb(main):005:0> make_change(37, [25, 10, 5, 1])
=> [25, 10, 1, 1]

Entendeu?! Agora vamos implementar o método, somente o método, não farei nenhuma classe. Primeiro vamos fazer alguns testes antes de criar o método:

require "test/unit";

class ChangeTest < Test::Unit::TestCase
  
  def test_should_raise_error_when_change_is_impossible
    assert_raise(ChangeError) do
      make_change(23, &#91;10, 5&#93;);
    end
  end
  
  def test_should_accept_diferent_coins
    assert_equal &#91;17, 17, 4&#93;, make_change(38, &#91;17, 4&#93;);
    assert_equal &#91;52&#93;, make_change(52, &#91;52&#93;);
  end
  
  def test_should_give_minimun_number_of_coins
    assert_equal &#91;25, 10, 1, 1&#93;, make_change(37);
    assert_equal &#91;1, 1, 1&#93;, make_change(3);
    assert_equal &#91;3, 3&#93;, make_change(6, &#91;3&#93;);
  end
  
end
&#91;/sourcecode&#93;

Se a troca for impossível com as moedas fornecidas, o método vai devolver uma exceção do tipo ChangeError. O método também tem por default moedas de 25, 10, 5 e 1 para serem usadas. Feitos os testes, vamos partir para a implementação, para isso precisaremos adicionar um método <b>sum</b> na classe Array que soma os elementos de dentro do Array:


class Array
  
  def sum
    inject{|sum, n| sum + n;};
  end
  
end

Pronto, agora podemos partir para a implementação:

class ChangeError < StandardError; end

def make_change(amount, coins=&#91;25, 10, 5, 1&#93;)
  change = coins.sort.reverse.inject(&#91;&#93;) do |change, coin|
    change << coin until change.sum + coin > amount;
    change;
  end
  raise ChangeError unless change.sum == amount;
  change;
end

Na linha 4, eu ordeno o Array de maior para menor e uso o método inject, que é basicamente responsável por reduzir o Array a um valor. Nesse caso dentro do bloco de código eu coloco as moedas no Array change até que elas ultrapassarem o valor total, e devolvo esse Array. Na linha 8 eu checo se a soma do Array change é igual ao valor pedido, se não for retorna uma exceção ChangeError.

Não foi muito difícil, tem desafios mais elaborados no site, vale a pena dar uma conferida. Fiquei sabendo também que parece que esse é um dos últimos desafios do Ruby Quiz.

Powered by ScribeFire.


Ruby 1.9

janeiro, 1 - 2008

Antes de tudo um feliz ano novo para todos! Como todos já devem saber o Ruby 1.9 já foi lançado, e como um presente de natal, justamente no dia 25. Como o próprio Matz disse, essa ainda não é uma versão totalmente estável e nem para ser usada em produção, não a receba como substituta do Ruby 1.8, ela é experimental ainda. Tivemos grande mudanças como YARV, threads nativas, mais splats de Arrays, UTF-8, métodos de Enumerable sem bloco e etc, veja mais mudanças e um tutorial para instalar o Ruby 1.9.

Powered by ScribeFire.


Ruby Rocks!

setembro, 10 - 2007
class Proxy
  def self.execute(code, &action)
    self.new(&action).instance_eval(&code);
  end
  def initialize(&block)
    @block = block;
  end  
  def method_missing(*args, &block)
    args += instance_eval(&block) if block_given?
    @block.call(*args.flatten);
  end
end

def words(&block)
  Proxy.execute(block){|*args| args.map{|obj| obj.to_s};}
end

p words{hello world! ruby is great}

Ok, ok, não serve pra nada, ainda tem warnings, problemas com keywords, etc. Mas parece mágica!

Powered by ScribeFire.


Code Contest: Mega Sena Acumulada

setembro, 1 - 2007

Vindo do blog do Walter Cruz, em resposta ao desafio do blog Macaco Chefe.

Escrever em qualquer linguagem de programação um programa que realize 100.000 sorteios de um numero entre 1 e 60 e mostre na tela os 6 mais freqüentes.

Ganha quem fizer em menos linhas, consegui fazer em 1 linha com Ruby!

Array.new(100000){rand(60)+1}.inject(Hash.new(0)){|hash, i| hash if hash[i] += 1}.invert.sort.reverse[0...6].each{|t, n| puts "#{n} repeated #{t} times"}

Tipo de coisa que não faria normalmente, pela complexidade que gera para entender o código, mas acho que valeu!

Powered by ScribeFire.


Sistema De Arquivos E Zip

julho, 19 - 2007

Fiz um arquivo Ruby com os comandos básicos para mexer em arquivos, diretórios, zipar, etc..
Para mexer com arquivos Zip será necessária a biblioteca RubyZip, se você instalou o RubyGems junto com o Ruby, é só rodar o comando abaixo.

gem install rubyzip

Como as funções são básicas está tudo explicado nos comentários, qualquer comenta aí!

Baixar files_tutorial.rb

Powered by ScribeFire.