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.

Anúncios

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.


Internet Explorer 8 Nos Padrões

dezembro, 20 - 2007


Esse vídeo não é falso (espero!), o Internet Explorer 8 passou no teste Acid2. Finalmente podemos ver uma luz no final do túnel em relação aos padrões e o Internet Explorer. Isso será um fato histórico se a versão final comprir o que promete. Há quanto tempo você xinga a Microsoft enquanto desenvolve um layout?! Isso vai acabar! Isso não quer dizer que usarei IE agora, nem perto disso, Firefox está a anos-luz dele, mas é uma notícia que merece ser comemorada. Fiquei sabendo no Revolução Etc, notícia original no site da evangelizadora dos padrões, que foi contratada pela Microsoft, Molly: Sim senhoras e senhores, nós temos um sorriso.

Powered by ScribeFire.


Rails 2.0 Chegou

dezembro, 7 - 2007

Finalmente chegou o tão esperado Rails 2.0, na versão 2.0.1 com algumas correções de última hora. Muitas novidades chegaram, confira algumas aqui mesmo ou veja alguns vídeos sobre o Rails 2.0 no Railscasts (Simplificando Views com Rails 2.0, Fixtures no Rails 2.0 e Autenticação HTTP). Para instalar é só rodar:

gem install rails -y

Ou se o de cima não funcionar:

gem install rails -y --source http://gems.rubyonrails.org

Se a versão do RubyGems não for a mais nova pode estar dando erros (como aqui), então rode antes:

gem update --system

Prometo que voltarei a postar mais regularmente.

Powered by ScribeFire.


Aptana Studio 1.0

outubro, 30 - 2007

Finalmente a fase beta do Aptana (agora Aptana Studio) acabou! Depois de dois anos de desenvolvimento e mais de 1 milhão de downloads, eles chegaram a versão 1.0. Agora o Aptana vem em duas versões, Community e Professional. Algumas das funcionalidades adicionadas:

  • Pré-visualização de CSS
  • Arrastar e soltar códigos
  • Tons da interface acabados
  • Sistema de ajuda dinâmico aperfeiçoado

O que realmente espero é que seja mais estável. Dá uma passada lá no site do Aptana, to baixando agora.

Powered by ScribeFire.


Quebra-Pau De Linguagens! Copa Do Mundo

outubro, 16 - 2007

Galera, como havia dito anteriormente, o Webly lançou seu 1º Quebra-Pau De Linguagens. O objetivo é avaliar a linguagem e o programador. O tema é Copa Do Mundo, o participante deverá fazer um programa que crie jogos entre os 16 paises citados e defina os vencedores, fazer o mesmo com os vencedores até chegar ao campeão! A idéia foi do Luis, que participará também (acho). Me aguardem que também vou participar com Ruby e quem sabe Javascript também. Passem ! Se tudo der certo e muitos participarem faremos um campeonato!

Powered by ScribeFire.


Rails 2.0 Chegando

outubro, 1 - 2007

Acabou de sair do Riding Rails o Preview Release do Rails 2.0. Antes de se lançarem a versão 2.0 final eles lançarão o Rails 1.2.4, que vai ter muitos bugs consertados e warnings de métodos deprecados para sua aplicação estar prontar para o novo Rails.
Nessa nova versão tivemos mudanças no ActionPack, não tantas no ActiveRecord, o ActiveWebService saiu e entrou ActiveResource, e etc. Praticamente o framework ficou mais limpo, mais coeso. Vou listar algumas delas que achei interessante la do post, lembrando que não testei nenhuma delas:

ActionPack

Organização Da View

Agora os templates tem um novo formato para serem nomeados, ele é action.formato.renderizador. Exemplos:

  • Páginas que serão renderizadas para HTML com o ERB: action.html.erb.
  • Usar o Builder que renderiza aquele XML para um feed: action.atom.builder.
  • Renderizar usando outro renderizador como o HAML: action.html.haml.

Tratamento de erros

Antes você redefinia um método para tratar os erros que ocorriam, tendo que fazer um case para identificar o tipo de cada erro. Agora você ganhou um método declarativo nos controles chamado rescue_from, que chama um determinado método para cada tipo de erro. Exemplo:

class PostsController < ApplicationController
  rescue_from User::NotAuthorized, :with => :deny_access

  protected
  def deny_access
    #...
  end
end

Sai O Paginator Clássico

O paginator clássico agora só está disponível como um plugin (classic_pagination), foi retirado do core do Rails. Aproveitando que ele saiu, aconselho vocês a usarem o plugin will_paginate.

ActiveRecord

Migrations Mais Atraentes

Agora ao invés de ter que ficar chamando column para cada novo atributo na coluna, você pode chamar o tipo do atributo (string, integer, datetime, etc.). Isso já implorava por um method_missing há um tempo, mais Ruby/Rails Like.
Antes você usava:

create_table :posts do |t|
  t.column :body, :string, :null => false;
  t.column :user_id, :integer;
  t.column :created_at, :datetime;
end

Agora pode usar:

create_table :posts do |t|
  t.string   :body, :null => false;
  t.integer  :user_id;
  t.datetime :created_at;
end

Alguns Quilos A Menos

Para deixar o ActiveRecord um pouco mais limpo removeram os acts_as_etc do core, eles estão disponíveis como plugins, para instalar o acts_as_list, por exemplo, é só rodar script/plugin install acts_as_list. Removeram também os adaptadores de bancos de dados comerciais, agora o Rails só vem com adaptadores para os bancos MySQL, SQLite e PostgreSQL. Mas se quiser usar os outros bancos, os adaptadores estão disponíveis como gems, para instalar o adaptador para o Oracle, por exemplo, é só dar um gem install activerecord-oracle-adapter.

Vale lembrar que ainda não é a versão final, algumas coisas ainda podem mudar. Ah, não precisa dizer que os métodos hoje deprecados serão eliminados. Essa nova versão promete ser mais estável, mais divertida e mais limpa.

Powered by ScribeFire.