Fibonacci Series using classes and methods - ruby

I have written a fibonacci series method and tried calling it. It works fine with the following code:
module Fibonacci
class Operation
def fibonacci(n)
num1 = 0
num2 = 1
while num2 < n
puts num2
num1, num2 = num2, num1 + num2
end
end
end
res = Operation.new
puts 'Enter the number upto which Fibonacci needs to be printed:'
n = gets.chomp.to_i
res.fibonacci(n)
end
But I want to have a seperate method for accepting input within the class and calling it.
module Fibonacci
class Operation
def input
puts 'Enter the number upto which Fibonacci needs to be printed:'
n = gets.chomp.to_i
end
def fibonacci(n)
num1 = 0
num2 = 1
while num2 < n
puts num2
num1, num2 = num2, num1 + num2
end
end
end
res = Operation.new
res.input
res.fibonacci(n)
end
Getting an Error!..I'm a newbie, Would be helpful if I get a support..Thank You

As it stands, your code doesn't use the return value of your input function; it disappears into the ether, and your caller has an undefined n it's attempting to access. If you write your calling code as:
res = Operation.new
res.fibonacci(res.input)
Then you pass the return value from res.input into res.fibonacci and your immediate problem is resolved.
Beyond this, I believe there are noteworthy design issues in your code which you may consider. Functions should be modular and avoid side-effects such as printing, which severely limit their usefulness and flexibility. What if you wish to generate Fibonacci numbers and use them for something else in your program? You have to rewrite the whole function again. If you write it once to populate and return an array, you let the caller decide whether to print the output, save it in a database, send it through a socket, reverse it, send it into another function (you get the idea).
Seek to avoid hard-coded values like string and numbers. Your input function can't work for anything but collecting Fibonacci numbers. What if you let the caller decide what the message is? Then, when you add more math functions to your Operation class, you can reuse the same input routine.
I would also contend that a function like input doesn't belong in an Operator class. I can see it used as a utility function in that class, but it's independent of Operator-like stuff and is too small to warrant its own function in any case.
Here's a re-write that somewhat mitigates these issues:
module Fibonacci
class Operation
def input(message)
puts message
gets.chomp.to_i
end
def fibonacci(n)
num1 = 0
num2 = 1
result = []
while num2 < n
result << num2
num1, num2 = num2, num1 + num2
end
result
end
end
res = Operation.new
puts res.fibonacci(res.input 'Enter the number upto which Fibonacci needs to be printed:')
end
And a sample run:
Enter the number upto which Fibonacci needs to be printed:
15
1
1
2
3
5
8
13

Change code to:
def input
puts 'Enter the number upto which Fibonacci needs to be printed:'
n = gets.chomp.to_i
fibonacci(n)
end
And remove res.fibonacci(n).
Here is the full code:
module Fibonacci
class Operation
def input
puts 'Enter the number upto which Fibonacci needs to be printed:'
n = gets.chomp.to_i
fibonacci(n)
end
def fibonacci(n)
num1 = 0
num2 = 1
while num2 < n
puts num2
num1, num2 = num2, num1 + num2
end
end
end
res = Operation.new
res.input
end
Hope this helped.

It could incredibly help if you have specified what exact error do you have, but let me guess: it’s kinda “NameError: undefined local variable or method `n'”
That happens because you have not passed an argument in your call to fibonacci. You have an option to fallback to getting the variable from the user input if none was specified:
class Operation
def input
puts 'Enter the number upto which Fibonacci needs to be printed:'
gets.chomp.to_i
end
def fibonacci(n = -1)
# HERE
n = input if n <= 0
num1 = 0
num2 = 1
while num2 < n
puts num2
num1, num2 = num2, num1 + num2
end
end
end
res = Operation.new
res.fibonacci(5)
#⇒ 1 1 2 3
res.fibonacci
#⇒ 'Enter the number ...'

Related

Ruby- prime number unique and duplicates

I'm just learning Ruby :) and Im trying to create a simple prime-number program where all the primes of a number are printed.
I'm getting errors where the prime and nonprime numbers are mixed up
(ie: input of 9 will get you all nonprimes).
I'm sorry for such a beginner question - I'm struggling alot and need some help :)
puts "Enter a number please "
num = gets.chomp.to_i
i = 2
number = 2
while i < num
if number % i == 0
prime = false
end
i += 1
end
if prime == true
puts "#{number} is prime"
else
puts "#{number} is not prime"
end
number += 1
end
while i < num
if number % i == 0
prime = false
end
i += 1
end
# ...
It looks like that first end is meant to be an else.
It's easier to catch these things when you simplify your code, e.g. this method reduces to this (although there are other issues with it):
i = 2
number = 2
while i < num
(number % i).zero? ? prime = false : i += 1
puts "#{number} is #{'not ' unless prime}prime"
number += 1
end
End error is because of else
while i < num
if number % i == 0
prime = false
else
i += 1
end
if you have a short If - neater is writing it like:
if-condition ? 1 : 0
and in your case while is.. not the nicest choice - you should use range
(1...3).map{|x| puts(x) }
{} - allows multiline(with do end end)
this prints [1,2]
(1..3).map{|x| x*2 }
would be [2,4,9]
This should be enough hints of how to play around with your code without ruining the process.

Ruby looping program gives error

Here's what I wrote to check if a number is prime or not
print "Enter number : "
num = gets.chomp
i = 1
boo = true
while (i<num)
if (i%num==0)
boo=true
end
i++
end
if (boo==true)
puts (num+"is a prime number")
else
puts (num+"is not a prime number")
end
This gives an error, how can I fix it?
The output from cmd prompt:
Some problems:
++ operator doesn't exist in Ruby, you can use += 1 instead
your num is a string, you can make it a number with to_i method, like num.to_i
if the reminder of your number divided by a precedent number is zero you should set to false, not true
if you start at 1 your number will result always prime
Anyway, in a more idiomatic Ruby you can write this code something like
print "Enter number : "
num = gets.chomp.to_i
prime = (2..num - 1).all? { |i| num % i != 0 }
if prime
puts "#{num} is prime"
else
puts "#{num} is not prime"
end

Ruby: Factorial Recursion

The difference between the two methods occurs at second if condition. The if condition in the first method is "if num <= 1" and the if condition in the second method is "if num = 1". I mapped out both methods on a piece of paper step by step but I don't understand why the factorial2 returns 1 instead of 6. On paper, I get 6 for both methods.
def factorial1(num)
if num < 0
return "Please use a positive number"
end
if num <= 1
1
else
num * factorial(num-1)
end
end
puts factorial1(3)
#returns 6
def factorial2(num)
if num < 0
return "Please use a positive number"
end
if num = 1
1
else
num * factorial(num-1)
end
end
puts factorial2(3)
#returns 1
if num = 1
Comparator operator is ==, not = (assignment operator).
Also don't forget to use return keyword, it is good convention to make each branch return something.
def fact(n)
return 1 if n==0
return n * fact(n-1)
end
puts "Enter number"
n=gets.to_i
a=fact(n)
puts a

How do I calculate the factorial of a number in Ruby?

Alright, so I asked an earlier question on my syntax error. I got rid of the errors, but the program doesn't do what it was intended to do. My math is wrong and doesn't find the number of trailing zeros. Here is my code:
num = " "
a = 0
sumOfFact = 1
def factorial
num = gets.to_i
a = num
(1..num).each do |a|
if a != 1
sumOfFact *= a
a -= 1
else
break
end
end
end
for c in 1..sumOfFact
if sumOfFact / c == 10
zeros += 1
end
end
factorial()
puts sumOfFact
puts zeros
Well, first, you should do the gets outside your method. Your method should accept a param. Second, why do you need the condition?
You want the multiplication from 1 to n to get the factorial. You should get started with this:
def factorial(n)
total = 1
(1..n).each do |n|
total *= n
end
total
end
puts factorial(gets.to_i)
Next is factorial with inject in case you want to learn new syntax :-)
def factorial(n)
n == 0? 1 : (1..n).inject(1) { |total, i| total*= i; total }
end
puts factorial(gets.to_i)
As #pjs commented below, here's a beautiful way of doing factorial!
def factorial(n)
n == 0? 1 : (1..n).inject(:*)
end
And, a final enhancement:
def factorial(n)
(1..n).inject(1, :*)
end
Supposing that n is a non-negative integer number, you can define a method to calculate the factorial:
def factorial(n)
tot = 1
(1..n).each do |n|
tot *= x
end
tot
end
Examples of its usage:
puts factorial(0) # 1
puts factorial(1) # 1
puts factorial(2) # 2
puts factorial(3) # 6
puts factorial(4) # 24
puts factorial(5) # 120
If you wan't to read the user input, call it like this:
puts 'Type the non-negative integer:'
n = gets.to_i
puts factorial(n)
class Factorial
attr_reader :num
def initialize(num)
#num = num
end
def find_factorial
(1..num).inject(:*) || 1
end
end
number = Factorial.new(8).find_factorial
puts number
Or you could just simply write:
(1..num).inject(:*) || 1
Try this too. Hope this helps anyone having the same problem in some way.
Method for finding the factorial of any number:
def factorial(number)
for i in 1...number do
number *= i
end
number
end
puts factorial(5)

Ruby - Prime Number calculator

I need some feedback to figure out why I cant puts or print anything from my methods on the screen. This is a simple script I wrote to solve the problem of finding the 1001st prime number. Thanks
def primes
# iterates through numbers until it has the 1001th prime number and returns it.
# I chose to create the num_primes variable instead of counting the number of
# elements in in_prime_array every iteration
# based upon a guess that it would be faster to check.
is_prime_array = []
num_primes = 0
i = 2
loop do
is_prime_array << i && num_primes += 1 if is_prime?(i) == true
i += 1
break if num_primes == 1001
end
is_prime_array[1001]
end
def is_prime? (num)
# Checks to see if the individual number given is a prime number or not.
i = 2
loop do
if i == num
return true
elsif num % i == 0
return false
else
i += 1
end
end
end
Thanks for any help!
EDIT
I took your advice and tried this pice of code:
def is_prime? (num)
# Checks to see if the individual number given is a prime number or not.
i = 2
loop do
if i == num
return true
elsif num % i == 0
return false
else
i += 1
end
end
end
i = 0
count = 0
loop do
count += 1 if is_prime?(x)
puts "#{i}" if count == 1001
break
end
It still returns nothing. Hummm
i = 0
count = 0
loop do
if is_prime(i)
count += 1
end
if count == 10001
puts "#{i}"
break
end
end
Simple method :)
It's an off-by-one error. If you have 1001 elements in an array, the last element will be at index 1000.
Where you have
is_prime_array[1001]
Change it to
is_prime_array[1000]
And you can do this:
puts primes
=> 7927
You could also have
is_prime_array.last
instead of a specific index number.
What are you trying to "puts"? The first thing I notice is that there is no call to primes in the file, so nothing will happen if you try to run this code by itself. Maybe that's why you don't see anything printed.
Here's an example of how to print a few variables inside your loop:
loop do
...
puts "At iteration #{i}, we have prime=#{is_prime?(i)}"
If you don't know, enclosing a statement with #{<statement goes here>} inside a string is the same as appending the return value of <statement goes here> to the string at that position. This is the same as "Str " + blah + " rest of str" in a language like Java.

Resources