How do I write a math formula? - ruby

I need to write the following formula in code:
C ((i/100)(n/365)+1)
This means that i should be divided by 100, n should be divided by 365, both results must be multiplied, the resulting number should be added 1 and the resulting number should be multiplied by C.
I was able to write the following code, but there is an error in the math operation I cannot fix:
puts "Insert money to invest:"
money_invested = gets.to_i
puts "Indicate in days the period of deposit:"
time_investment = gets.to_i
puts "Indicate interest rate:"
interest_rate = gets.to_i
investment_calculation = money_invested * (([interest_rate / 100] [time_investment / 365]) + 1)
puts "Your refund will be $#{investment_calculation.round(2)}."

try this:
investment_calculation = money_invested * (((interest_rate / 100) * (time_investment / 365) + 1))
1) you used [] instead of ().
in ruby [] corresponds to a list
2) you need to use * to multiply the results of (interest_rate / 100) and (time_investment / 365)
EDIT
If you are using decimals your code wouldn't work, you would need to use to_f instead of to_i
like this: interest_rate = gets.to_f

When you divide two integers in Ruby, you get integer division (the result is an integer):
irb(main):001:0> 1343/1000
#=> 1
If you want a floating point number, then you need at least one of the two numbers to be a floating point value:
irb(main):002:0> 1343/1000.0
#=> 1.343
irb(main):003:0> 1343.0/1000
#=> 1.343
You can do this by making the user input into floating point numbers instead of integers (use to_f instead of to_i), or by using floating point constants in your formula. The first will suffice, and makes sense, in case the user types in 50.75 for their money. ("50.75".to_i #=> 50)
puts "Insert money to invest:"
money_invested = gets.to_f
puts "Indicate in days the period of deposit:"
time_investment = gets.to_f
puts "Indicate interest rate:"
interest_rate = gets.to_f
investment_calculation = money_invested * (1 + interest_rate/100 * time_investment/365)
puts "Your refund will be $%.2f." % investment_calculation
Note that I've used String#% method with %.2f to format your number to two decimals. This is because 3.round(2) yields the number 3.0 and not the string "3.00" as you desire.

Related

Ruby: Am I using the correct scope?

I come from a JavaScript background and wrote this similar to how I would in javascript. I am writing it in Ruby.
This is a codewars exercise.
n being 0 and 1 returns 0.00 and 1.00 as expected. Every other positive natural number returns 0.
# Task:
# Your task is to write a function which returns the sum of following series upto nth term(parameter).
# Series: 1 + 1/4 + 1/7 + 1/10 + 1/13 + 1/16 +...
# Rules:
# You need to round the answer to 2 decimal places and return it as String.
# If the given value is 0 then it should return 0.00
# You will only be given Natural Numbers as arguments.
# Examples:
# SeriesSum(1) => 1 = "1.00"
# SeriesSum(2) => 1 + 1/4 = "1.25"
# SeriesSum(5) => 1 + 1/4 + 1/7 + 1/10 + 1/13 = "1.57"
def series_sum(n)
sum = 0
if n == 0
return 0.00
elsif n == 1
return 1.00
else
n.times do |i|
if i == 1
sum += 1
break
end
sum += 1/( 1 + (3 * (i - 1)) )
end
end
return sum
end
puts series_sum(0)
puts series_sum(1)
puts series_sum(2)
puts series_sum(4)
puts series_sum(5)
A couple of things to note:
- Ruby has reduce method that can sum up a list of numbers: https://apidock.com/ruby/Enumerable/reduce
- You don't need to explicitly return from your method. Ruby automatically returns the last statement in your method.
I've modified your solution, and this should work:
def series_sum(n)
if n > 1
sum = (1..n).inject { |sum, i| sum + (1/(1.to_f + (3 * (i - 1)))) }
else
sum = n
end
'%.2f' % sum
end
When you are expecting a decimal number in a division, always make sure that either the numerator or the denominator is in float, hence the reason for the 1.to_f.
'%.2f' is a string format to ensure the final answer is returned in 2 decimal places.
There are two parts to this question.
How to display an operation's result as a float value?
1/2 # this will give 0
1.0/2 # this will give 0.5
How to limit a float value to 2 decimal places?
You can use the round function
22.0/7 # this will give pi value - 3.142857142857143
(22.0/7).round(2) # this will give 3.14
The two answers above can be combined to get your answer. I would leave it as an exercise for you to come up with the exact code to solve your problem.
def series_sum(n)
return "0.00" if n.zero?
sprintf("%.2f", (0..n-1).sum { |m| 1.fdiv(3*m+1) }.round(2))
end
series_sum(0) #=> "0.00"
series_sum(1) #=> "1.00"
series_sum(2) #=> "1.25"
series_sum(3) #=> "1.39"
series_sum(4) #=> "1.49"
series_sum(5) #=> "1.57"
See Kernel#sprintf. One could alternatively use String%, which shares sprintf's formatting directives:
"%.2f" % (0..n-1).sum { |m| 1.fdiv(3*m+1) }.round(2)
I am not aware of the existence of a closed-form expression for this partial sum. Though not relevant to the question, this partial sum can be shown to be divergent.

Insert chosen number within range, squared and cubed

I am trying to set a range for allowed user inputted numbers. Then, I want to print that chosen number squared and cubed.
I tried the following:
class Range
def clamp(min, max)
self < min ? min : self > max ? max : self
end
end
class Multiply
def initialize(id, squared, cubed)
#id = num
#squared = (num * num)
#cubed = (num * num * num)
end
end
# #limit = (params[:limit] || 10).clamp(0, 100)
puts 'Please insert your favorite number between 1 and 100.'
num = gets.to_i
puts 'You picked ' + num.to_s + '?'
puts 'You picked ' + num.to_s.Multiply.squared + '?'
The #limit throws 'params' not found.
How can I run num through classes Range and Multiply before it puts?
I am trying to set a range for 'allowed' user inputted numbers, then I
want to print that chosen number squared, and cubed.
Use the clamp method available to Numeric via the Comparable module:
input = '110'
clamped = input.to_i.clamp(0,100)
puts clamped
#100
You can attain powers of numbers with Integer#** or Float#**. If one must produce DIY methods by extending core classes, then you can for example extend the Numeric class by defining the methods clamp, square and cube there. square could be:
class Numeric
def square
self ** 2
end
end
10.square #=> 100

Handling numbers near infinity (large and small)

I'm trying to do this operation with Ruby:
1.2679769534809603e-175
*
792621072814943158937574954417696054502273470568077747007887743862285047941581535541498718312275086275679893343076013862361579680670972527976009279036348551929550827607601145450876014530359530008733947699274904382825445634899233107885545828612637824213482759975963581961375904743254634250508637523339809985946128242523687347261107994804323593105039052556442336528920420940313
I know the answer is 1.005025 (truncated to 6 decimal places), but I keep getting the above equation returning infinity. Why is that? I'm not going smaller than the first number, nor larger than the second number.
So two questions: Why is it returning infinity? And how could I get the correct answer to return?
If you want to minimize precision issues, go Rational.
irb(main):001:0> a = 1.2679769534809603e-175.to_r
=> (4519585589664361/35644067325173400145634153169533525975728347712879374457649941546088087243817792082077443838416964060770643043543706307114755505635745609361348916560329798345718708393439569922522454626926592)
irb(main):002:0> b = 792621072814943158937574954417696054502273470568077747007887743862285047941581535541498718312275086275679893343076013862361579680670972527976009279036348551929550827607601145450876014530359530008733947699274904382825445634899233107885545828612637824213482759975963581961375904743254634250508637523339809985946128242523687347261107994804323593105039052556442336528920420940313
=> 792621072814943158937574954417696054502273470568077747007887743862285047941581535541498718312275086275679893343076013862361579680670972527976009279036348551929550827607601145450876014530359530008733947699274904382825445634899233107885545828612637824213482759975963581961375904743254634250508637523339809985946128242523687347261107994804323593105039052556442336528920420940313
irb(main):003:0> a * b
=> (3582318778758723293544808766608477208802528713781684733988516016569614012687037578637365969280014511731955915723620354805192948677648150726285518854921630223111683624006805801219885647290056974705691181872855057825408797944671825308998484595184690885834492619019604611321846034964892047367198046135813425296123973237329110031154221763204044754826429491855167243281047603348342563725684284993/35644067325173400145634153169533525975728347712879374457649941546088087243817792082077443838416964060770643043543706307114755505635745609361348916560329798345718708393439569922522454626926592)
irb(main):004:0> (a * b).to_f
=> 1.005025253172702e+200
After some playing around I believe your problem comes from autopromotion of the second number to perform float arithmetic.
puts "Original math"
z = 1.2679769534809603e-175 * 792621072814943158937574954417696054502273470568077747007887743862285047941581535541498718312275086275679893343076013862361579680670972527976009279036348551929550827607601145450876014530359530008733947699274904382825445634899233107885545828612637824213482759975963581961375904743254634250508637523339809985946128242523687347261107994804323593105039052556442336528920420940313
puts z
Infinity
puts
puts "Save variables individually and inspect"
x = 1.2679769534809603e-175
y = 792621072814943158937574954417696054502273470568077747007887743862285047941581535541498718312275086275679893343076013862361579680670972527976009279036348551929550827607601145450876014530359530008733947699274904382825445634899233107885545828612637824213482759975963581961375904743254634250508637523339809985946128242523687347261107994804323593105039052556442336528920420940313
puts x
1.2679769534809603e-175
puts y
792621072814943158937574954417696054502273470568077747007887743862285047941581535541498718312275086275679893343076013862361579680670972527976009279036348551929550827607601145450876014530359530008733947699274904382825445634899233107885545828612637824213482759975963581961375904743254634250508637523339809985946128242523687347261107994804323593105039052556442336528920420940313
z = x * y
puts z
Infinity
puts "What? none of the numbers was Infinity??"
puts "Or was it?? auto promoted y"
y = 792621072814943158937574954417696054502273470568077747007887743862285047941581535541498718312275086275679893343076013862361579680670972527976009279036348551929550827607601145450876014530359530008733947699274904382825445634899233107885545828612637824213482759975963581961375904743254634250508637523339809985946128242523687347261107994804323593105039052556442336528920420940313.0
puts y
Infinity
In most languages anything * Infinity = +- infinity

Ruby: What is the difference between these two blocks of code?

Below, I will provide 2 different blocks of code:
Code Block A, while I know there are better ways of writing it, it's where my thought process was initially going
Code Block B is a much more concise way of the aforementioned code
Code Block A:
print "How much was your meal?"
meal_cost = Float(gets)
meal_cost = '%.2f' % meal_cost
print "What is the tax percentage in your state?"
tax_percent = Float(gets)
tax_percent = '%.2f' % tax_percent
tax_value = meal_cost.to_f * (tax_percent.to_f * 0.01)
tax_value = '%.2f' % tax_value
meal_with_tax = tax_value.to_i + meal_cost.to_i
meal_with_tax = '%.2f' % meal_with_tax
print "What percentage would you like to tip?"
tip_percent = Float(gets)
tip_value = (tip_percent.to_i * 0.01) * meal_with_tax.to_i
tip_value = '%.2f' % tip_value
total_cost = tip_value.to_i + meal_with_tax.to_i
total_cost = '%.2f' % total_cost
puts "The pre-tax cost of your meal was $#{meal_cost}."
puts "At #{tax_percent}%, tax for this meal is $#{tax_value}."
puts "For a #{tip_percent}% tip, you should leave $#{tip_value}."
puts "The grand total for this meal is then $#{total_cost}"
Code Block B:
puts "How much was your meal?"
meal_cost = Float(gets)
puts "Please enter your tax rate as a percentage (e.g., 12, 8.5)"
tax_percent = Float(gets)
puts "What percentage of your bill would you like to tip? (e.g., 15)"
tip_percent = Float(gets)
tax_value = meal_cost * tax_percent/100
meal_with_tax = meal_cost + tax_value
tip_value = meal_with_tax * tip_percent/100
total_cost = meal_with_tax + tip_value
print "The pre-tax cost of your meal was $%.2f.\n" % meal_cost
print "At %d%%, tax for this meal is $%.2f.\n" % [tax_percent, tax_value]
print "For a %d%% tip, you should leave $%.2f.\n" % [tip_percent, tip_value]
print "The grand total for this meal is then $%.2f.\n" % total_cost
For some reason, in Code Block A, the following lines:
meal_with_tax = tax_value.to_i + meal_cost.to_i
meal_with_tax = '%.2f' % meal_with_tax
returns 22 instead of 22.4
Can someone help me understand why?
to_i returns an integer.
you may want to use to_f to maintain precision
or value.round(1) may be the solution you're looking for
When you are converting tax_value and meal_cost to integers with .to_i in code block a you are losing precision.
to_i stands for 'to integer'. An integer is a number without a decimal point, so anything after the deciaml point will get thrown away after you call to_i.
x = 22.123456
y = 22.999999
x == y #=> false
x.to_i == y.to_i #=> true

"wrong number of arguments" ArgumentError when using round

I am trying to convert a temperature from Fahrenheit to Celsius:
puts 'Convertir grados Fahrenheit a Celcius'
STDOUT.flush
x = gets.chomp
aprox = (x * 100.0).round(2) / 100.0
resultado = (aprox-32)/1.8
puts resultado
I use the correct formula for converting Fahrenheit to Celcius:
Celsius = Fahrenheit - 32 / 1.8
However, when I run this in the console, it gives me the following error:
`round': wrong number of arguments (1 for 0) (ArgumentError)
I've tried different things but I don't understand why this doesn't work.
In ruby version prior to 1.9.0 round does not take arguments. It rounds to the nearest integer (see the documentation about floats and the use of round)
Use this instead:
aprox = (x * 100).round() / 100.0
The whole point of multiplying and dividing by 100 is to round the last two digit of x.
You don't specify what version of Ruby you are using. That makes a difference, because in Rubies prior to 1.9 Float#round did not take a parameter. In 1.9+ it does.
>> RUBY_VERSION #=> "1.9.2"
>> pi = 3.141 #=> 3.141
>> pi.round #=> 3
>> pi.round(1) #=> 3.1
>> 3.141.round(1) #=> 3.1
activesupport (part of rails) also gives you Float#round(precision)

Resources