TDD in Ruby Course

Thursday, July 02, 2015

Colt Gem Released

Colt is a micro gem used to subscribe to a given plan using the Stripe API. The plans must already exist in your account. The current version can check Stripe credentials and Stripe API version.

 Source Code. You can find the different versions at Rubygems.org

Tuesday, June 30, 2015

Check Amazon S3 Credentials

1. gem install aws-s3
2. In IRB console : require 'aws/s3'
3.
AWS::S3::Base.establish_connection!(access_key_id: 'abcd', secret_access_key: 'secret')
AWS::S3::Service.buckets
AWS::S3::Bucket.find('your-existing-bucket-name')

It would be nice to steal code from aws-s3 gem to test if the credentials is valid or not.

ERROR: "https://rubygems.org" is not allowed by the gemspec, which only allows "TODO: Set to 'http://mygemserver.com'"

Problem: 

Not able to publish gem to rubygems.org

Resolution:

Delete the following lines from your-gem.gemspec file.

  if spec.respond_to?(:metadata)
    spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
  else
    raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
  end

how to use active support outside of rails

Error : NoMethodError: undefined method `hours' for 1:Fixnum

Resolution:

1. bundle open activesupport
2. Search for 'def hours', it is found in core_ext/numeric/time.rb
3. Add require 'active_support/core_ext/numberic/time.rb'

This is better than doing : require 'active_support/all'

Saturday, June 27, 2015

How to use Simplecov in gem development

1. Add the simplecov gem and start before anything else in test_helper.rb

$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
require 'simplecov'

SimpleCov.start

require 'rasam'
require 'minitest/autorun'

2. You can mark private methods as:
    # :nocov:
  to exclude from test coverage.
 
3. Run : rake test

4. Open coverage/index.html

Friday, June 26, 2015

How I resolved confusing tests and production code


Pair Ranking is very well defined problem solving technique. When my code become convoluted I had to switch my perspective to that of the user to improve the code and the tests. Read more about it here: TDD Beyond Basics : Outside In Perspective. This also shows you an example of how you could use this gem.

Searching for a given element in an array of arrays in Ruby

How to pull the number 3 from this list by searching for the value 'c'.

records =
[
 ["a","1"],
 ["b","2"],
 ["c","3"]
]

search_for = 'c'

Solution 1:

test = records.select{ |x| x[0] == search_for }

p test[0][1]

Solution 2:

p records.assoc(search_for).last

Playing with Rails 4.2.3

zepho-mac-pro:blog zepho$ rails g scaffold article title
      invoke  active_record
      create    db/migrate/20150626235457_create_articles.rb
      create    app/models/article.rb

  BLAH, BLAH, BLAH

zepho-mac-pro:blog zepho$ rake db:migrate
== 20150626235457 CreateArticles: migrating ===================================
-- create_table(:articles)
   -> 0.0015s
== 20150626235457 CreateArticles: migrated (0.0016s) ==========================

zepho-mac-pro:blog zepho$ rails c
Loading development environment (Rails 4.2.3)
2.2.2 :001 > Article
 => Article (call 'Article.connection' to establish a connection)
2.2.2 :002 > Article.count
   (0.1ms)  SELECT COUNT(*) FROM "articles"
 => 0

Thursday, June 25, 2015

Pair Ranking Algorithm

require 'highline/import'
require "pp"
require 'rasam'

include Rasam

options = ask("Enter your choices (or a blank line to quit):",
lambda { |ans| ans =~ /^-?\d+$/ ? Integer(ans) : ans} ) do |q|
  q.gather = ""
end

@pr = PairRank.new(options)
@saved_combinations = Array.new(@pr.combinations)
combinations = Array.new(@pr.combinations)

pair = combinations.shift

def get_user_choice_for(pair)
  choose do |menu|
    menu.prompt = "Please choose your favorite: "

    pair.each do |c|
      menu.choice(c) do
        say(c)

        rationale = ask("Why?  ")

        say(rationale)

        rc = RationalChoice.new(pair, c, rationale)
        @pr.make(rc)
      end
    end
  end
end

loop do
  p pair  
  get_user_choice_for(pair)
  break if combinations.empty?
  pair = combinations.shift
end


@pr.decisions.each do |d|
  p d.to_s
end


p @pr.score_for('A')
p @pr.score_for('B')
p @pr.score_for('C')

def handle_ties(pair)
  choose do |menu|
    menu.prompt = "Please choose your favorite: "

    pair.each do |c|
      menu.choice(c) do
        say(c)

        rationale = ask("Why?  ")

        say(rationale)

        rc = RationalChoice.new(pair, c, rationale)
        @pr.make(rc)
      end
    end
  end
end

loop do
  p 'Handling a tie'
  if @pr.tied_pair.empty?
    break
  else
    handle_ties(@pr.tied_pair)
   
    @pr.decisions.each do |d|
      p d.to_s
    end
   
    p @pr.score_for('A')
    p @pr.score_for('B')
    p @pr.score_for('C')
    p @pr.tied_pair
   
  end
end

find numbers that are same in an array ruby

a = [0,1,2,2,3,3]
x = a.find_all { |e| a.count(e) > 1 }
   
p x

Wednesday, June 24, 2015

Pair Ranking Gem Released

Select a single winner using votes that express preferences. This can also be used to create a sorted list of winners. rasam gem

Create Gem and Publish to Rubygems

$gem build rasam.gemspec
$gem push rasam-0.1.0.gem

Generate all combinations of a given length for a list of items

In Ruby 2.2.2:

 a = [1,2,3,4]
 a.combination(2)
 => # 

We need to call to_a on this enumerator:

 a = ['A', 'B', 'C', 'D']
 => ["A", "B", "C", "D"]
> a.combination(2).to_a
 => [["A", "B"], ["A", "C"], ["A", "D"], ["B", "C"], ["B", "D"], ["C", "D"]]

How to provide a default value for all elements in a hash

a = Hash.new(0)
 => {}
> a['x']
 => 0

`require': cannot load such file -- minitest/autorun

Install Minitest gem by running: bundle install

Eliminate spaces, -, +, *, /, = and parentheses in a string

Run:

str = "Revenue - Costs * (1 + Profitpercentage)"
p str.scan(/[A-Za-z]+/)

at http://rubyplus.biz/

You will see:

["Revenue", "Costs", "Profitpercentage"]

How to delete nested hash elements based on the elements properties

data = {
"total_records"=>3,
"records"=>
   [{"title"=>"Val1",
   "coins"=>1},
   {"title"=>"Val2",
   "coins"=>1},
   {"title"=>"Val3",
   "coins"=>1}]
}

p data

data['records'].delete_if{ |h| %w(Val1 Val2).include?(h['title']) }

p data

Output:

{"total_records"=>3, "records"=>[{"title"=>"Val1", "coins"=>1}, {"title"=>"Val2", "coins"=>1}, {"title"=>"Val3", "coins"=>1}]}
{"total_records"=>3, "records"=>[{"title"=>"Val3", "coins"=>1}]}

Two HERE Docs in Ruby 2.2.2

data = [
<<'EOT1', <<'EOT2'
more text
EOT1
and more
EOT2
]

p data

An error occurred while installing json (1.6.1), and Bundler cannot continue.

Make sure that `gem install json -v '1.6.1'` succeeds before bundling.
zepho-mac-pro:dynamic-menus zepho$ gem install json -v 1.6.1
Building native extensions.  This could take a while...
ERROR:  Error installing json:
ERROR: Failed to build gem native extension.

    /Users/zepho/.rvm/rubies/ruby-2.2.2/bin/ruby -r ./siteconf20150624-48402-1w7o7yz.rb extconf.rb
checking for ruby/re.h... yes
checking for ruby/encoding.h... yes
creating Makefile

make "DESTDIR=" clean

make "DESTDIR="
compiling generator.c
generator.c:952:47: error: too few arguments provided to function-like macro invocation
    VALUE result = rb_str_new(FBUFFER_PAIR(fb));
                                              ^
generator.c:952:11: warning: incompatible pointer to integer conversion initializing 'VALUE' (aka 'unsigned long') with an expression of type 'VALUE (const char *, long)';
    VALUE result = rb_str_new(FBUFFER_PAIR(fb));
          ^        ~~~~~~~~~~
1 warning and 1 error generated.
make: *** [generator.o] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/zepho/.rvm/gems/ruby-2.2.2@dmenu/gems/json-1.6.1 for inspection.
Results logged to /Users/zepho/.rvm/gems/ruby-2.2.2@dmenu/extensions/x86_64-darwin-11/2.2.0/json-1.6.1/gem_make.out


Resolution: Downgrade ruby from 2.2.2 to 2.1

Could not find coffee-script-source-1.1.3 in any of the sources

Resolution:

bundle update --source coffee-script-source

Top 6 Ruby Links for June 24, 2015


1. How to build a rails 5 api only and backbone application

2. Provisioning a Server for Rails Stack using Sunzi Gem

3. How to Setup Vagrant for Rails Development

4. Using the Rails 5 Attributes API Today, in Rails 4.2

5. Render Markdown views with Redcarpet and Pygment in Rails

6. Subscribing for events in rails_event_store