Skip to content

Factorial and test unit for factorial#2

Open
hemahg wants to merge 12 commits into
srijitamukherjee:masterfrom
hemahg:test_unit
Open

Factorial and test unit for factorial#2
hemahg wants to merge 12 commits into
srijitamukherjee:masterfrom
hemahg:test_unit

Conversation

@hemahg
Copy link
Copy Markdown

@hemahg hemahg commented Oct 3, 2019

No description provided.

Comment thread Hema/lib/first_project/power.rb Outdated
return result
else
power = -1*power
for i in (1..power) do
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or you could have done:

1.0/pow(num, -power)

But that is fine ;)

Comment thread Hema/lib/first_project/power.rb Outdated
class Power
def self.pow(num,power)
result = 1.0
if(power >=0)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parenthesis are not mandatory

Comment thread Hema/lib/first_project/power.rb Outdated
for i in (1..power) do
result = result*num
end
return result
Copy link
Copy Markdown

@hallelujah hallelujah Oct 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can return result at the end of the method

Comment thread Hema/lib/first_project/power.rb Outdated
for i in (1..power) do
result = result*(1/num)
end
return result.round(9)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is acceptable for the purpose of the excercise

@n = @n - 1
end
result
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be wary of indentation, it makes the code more readable.
You probably want to setup your IDE with correctly.

That makes me think of a good read for start https://github.com/rubocop-hq/ruby-style-guide




class Facttest < Test::Unit::TestCase
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please follow convention for file and directory namingnaming

@@ -0,0 +1,21 @@
require "test/unit"
require_relative "/home/hema/RoR-Learning-Path/Programming Foundations: Algorithms/Factorial-test/fact"
Copy link
Copy Markdown

@hallelujah hallelujah Oct 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not require_relative

Rubyists generally run test with include in load path option -I. e.g: ruby -Ilib:test test/my_example_test.rb

assert_equal(6, Fact.new(3).fact)
end

def test_Zero
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert_equal(1, Fact.new(0).fact)
end

def test_negative
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread Hema/test/power_test.rb
require 'first_project/power'

class PowerTest < TestBase
test 'powerofnumber' do
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the name is just a string, i think that it is easier to read like this: 😄

Suggested change
test 'powerofnumber' do
test 'power of number' do

And then when you run the test, it will convert it internally to power_of_number which is how we name methods in Ruby (this naming convention is called snake case)

Comment thread Hema/lib/first_project/power.rb Outdated
def self.pow(num, power)
result = 1
if power >= 0
for i in (1..power) do
Copy link
Copy Markdown

@Martouta Martouta Oct 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I am gonna say in this comment, I don't know if it is appropiate or if it is too early (too difficult at this stage), so if you find it too hard right now, do not worry and just ignore this comment 😂

In Ruby we usually write this for i in (1..power) do like (1..power).each do |i| and what it does is: for the instance (1..power) of the class Range, call its instance method each and run the block after the do with the i as the parameter of the block.

Alternatively, as you do not mind about the index at all, you can also use the instance method times of the class Integer, which you can use when either you don't care about the value of the index, or when it can start by 0.

So it would be:

power.times { result *= num }

Considering that { ... } is the same as do ... end 😄 .

You can also use inject of an Enumerable (which is mostly any object that can be iterated, like a Range or an Array for example), and then you do not need the result variable and it is shorter 😄 Although it is too inneficient for this and I wouldn't recommend it, but since this is for the sake of learning, it would be:

def self.pow(num, power)
  if power >= 0
    ([num] * power).inject(1) { |n, result| result * n } # Or even: ([num] * power).inject(:*) || 1
  else
    1.0 / pow(num, -power)
  end
end

What ([num] * power).inject(1) { |n, result| result * n } does is, first make an array of power elements, all of them containing num, and then iterate all of them, with a variable called result starting by 1, and for each iteration of the array save in that variable the value of result * num, which is what returns at the end.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And there could be also a recursive version of this method, which in code is usually simpler but you also need to check to what it does with the stack of memory 😄 This version would be:

def self.pow(num, power)
  if power == 0
    1
  elsif power > 0
    num * pow(num, power - 1)
  else # power < 0
    1.0 / pow(num, -power)
  end
end

And there are probably more efficient versions but for now this is enough 😄

Comment thread Hema/lib/first_project/power.rb Outdated
@@ -0,0 +1,15 @@
module Hema
class Power
Copy link
Copy Markdown

@Martouta Martouta Oct 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We spoke in private before but I rather put it here as well.
We don't usually create a class if we don't expect it to be ever instantiate it and for that we usually just make a module instead. Like this:

module Hema
  module Power
    def pow(...)
      ...
    end
  end
end

And from outside called like: Hema::Power.pow(...)

Copy link
Copy Markdown

@hallelujah hallelujah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation is good.

Now all comments are about Styling and using Ruby Core Library methods

end

def fact
if @n == 0
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We try to avoid many nested if for learning you have https://rubystyle.guide

You can also use rubocop to tell you what is bad styling in your code https://github.com/rubocop-hq/rubocop

raise 'negatives are not acceptable'
else
result = 1
while @n > 0
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As stateed by @Martouta, when you have Enumerable, try to read the docs and use some of the methods of this module.

Try to understand this simpler version is:

(1..n).inject(&:*)


def test_negative
Factorial_test::Fact.new(-5).fact
assert_raise do
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not work as you do not execute nothing inside the block.

Comment thread Hema/test/power_test.rb Outdated
class PowerTest < TestBase
test 'powerofnumber' do
assert_equal 4, Hema::Power.pow(2, 2)
assert_equal 1, Hema::Power.pow(2.0, 0)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are formatting/styling issues, see https://rubystyle.guide

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants