-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Factorial and test unit for factorial #2
base: master
Are you sure you want to change the base?
Conversation
Hema/lib/first_project/power.rb
Outdated
return result | ||
else | ||
power = -1*power | ||
for i in (1..power) do |
There was a problem hiding this comment.
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 ;)
Hema/lib/first_project/power.rb
Outdated
class Power | ||
def self.pow(num,power) | ||
result = 1.0 | ||
if(power >=0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parenthesis are not mandatory
Hema/lib/first_project/power.rb
Outdated
for i in (1..power) do | ||
result = result*num | ||
end | ||
return result |
There was a problem hiding this comment.
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
Hema/lib/first_project/power.rb
Outdated
for i in (1..power) do | ||
result = result*(1/num) | ||
end | ||
return result.round(9) |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Follow convention see https://github.com/srijitamukherjee/RoR-Learning-Path/pull/2/files#r331490367
assert_equal(1, Fact.new(0).fact) | ||
end | ||
|
||
def test_negative |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make it more readable
See https://github.com/srijitamukherjee/RoR-Learning-Path/pull/2/files#r331490367
require 'first_project/power' | ||
|
||
class PowerTest < TestBase | ||
test 'powerofnumber' do |
There was a problem hiding this comment.
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: 😄
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)
Hema/lib/first_project/power.rb
Outdated
def self.pow(num, power) | ||
result = 1 | ||
if power >= 0 | ||
for i in (1..power) do |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 😄
Hema/lib/first_project/power.rb
Outdated
@@ -0,0 +1,15 @@ | |||
module Hema | |||
class Power |
There was a problem hiding this comment.
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(...)
There was a problem hiding this 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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
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) |
There was a problem hiding this comment.
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
No description provided.