# Nill output message (classes)

I’m trying to practice and learn by making my first program. I just
started learning about classes so I decided to convert the whole program
so it has a class in it.
It was successful (kinda), but in the end I don’t know why but I’m
getting a nill message between the lines.
Doesn’t nill mean when an outputs value is 0?
Thank you for the help, I appreciate every suggestion!
I’m really enjoying ruby so far.

require_relative ‘font_bold’

class CreditCalculator

def initialize(balance, apr, payment)
@balance = balance
@mpr = Float(apr /12)
@payment = payment
end

def calculate
\$m_counter = 0
\$total = @balance

``````while @balance > 0
\$m_counter += 1
remaining_interest = @balance / 100 * @mpr
\$total += remaining_interest
@balance += remaining_interest
@balance -= @payment
principal = @payment - remaining_interest
interest_paid = @payment - principal

if @balance < 0 then @balance = 0 end

interest_paid = interest_paid.round(2)
principal = principal.round(2)
@balance = @balance.round(2)

puts "#{\$m_counter.to_s.ljust(7)} #{@payment.to_s.ljust(12)}
``````

#{interest_paid.to_s.ljust(17)} #{principal.to_s.ljust(21)}
#{@balance.to_s.ljust(1)}"
puts
end

end
end

puts “Welcome to your credit card payment calculator!”.bold
puts

balance = gets.chomp.to_f

apr = gets.chomp.to_f

puts “How much \$ would you like to pay every month?”
payment = gets.chomp.to_f

puts
puts “Month”.ljust(8).bold + “Payment”.ljust(13).bold + “Interest
Paid”.ljust(18).bold + “Principal Paid”.ljust(22).bold + “Remaining
Balance”.bold

debt = CreditCalculator.new(balance, apr, payment)
p debt.calculate

puts
puts “Monthly payment:” + “\$”.rjust(3) + “#{payment}”
puts “Balance payoff: #{\$m_counter.to_s.rjust(4)} months”
puts “Total payments:” + “\$”.rjust(4) + \$total.round(2).to_s

If you’re using IRB you’ll get “nil” as a return value when you perform
certain actions like creating a method. This is normal, it just shows
you that nothing is returned.

If you’re referring to nil outputs somewhere else, can you demonstrate?

I’m referring to the bill between the monthly results and the overall
results. That’s why I’m wondering because the method has already been
run with results and it still puts out the nil.
Could it be because I’m using the p not puts (making a method for
.to_s)?

Welcome to your credit card payment calculator!

50
18
How much \$ would you like to pay every month?
10

Month Payment Interest Paid Principal Paid Remaining
Balance
1 10.0 0.75 9.25 40.75

2 10.0 0.61 9.39 31.36

3 10.0 0.47 9.53 21.83

4 10.0 0.33 9.67 12.16

5 10.0 0.18 9.82 2.34

6 10.0 0.04 9.96 0.0

nil

Monthly payment: \$10.0
Balance payoff: 6 months
Total payments: \$52.38

The last action in the method “calculate” is “puts”. This returns nil.

On Sun, Oct 27, 2013 at 1:51 PM, Joel P. [email protected]
wrote:

The last action in the method “calculate” is “puts”. This returns nil.

To elucidate: you have the line `p debt.calculate`, where you probably
want
simply `debt.calculate`. The way it is now, you’re calling the method,
which does its own printing, and then you send the method’s return value
(nil) to `p`, which prints the nil.

FYI for your purposes, “gets.chomp.to_f” is the same as “gets.to_f”.

On Oct 27, 2013, at 11:09 , Joel P. [email protected] wrote:

If you’re using IRB you’ll get “nil” as a return value when you perform
certain actions like creating a method. This is normal, it just shows
you that nothing is returned.

Wrong. Nil is a value just like everything else. Something was returned:
nil.

On Oct 27, 2013, at 09:19 , Greg H. [email protected] wrote:

`````` puts "#{\$m_counter.to_s.ljust(7)} #{@payment.to_s.ljust(12)}
``````

#{interest_paid.to_s.ljust(17)} #{principal.to_s.ljust(21)}
#{@balance.to_s.ljust(1)}"

vs:

puts “%-7d %8.2f %8.2f %8.2f %8.2f” % [\$m_counter, @payment,
interest_paid, principal, @balance]

Am 27.10.2013 17:19, schrieb Greg H.:

def initialize(balance, apr, payment)
@balance = balance
@mpr = Float(apr /12)
@payment = payment
end

@balance = balance.to_f
@payment = payment.to_f

I would do conversion to float here, to make sure
nothing strange happens below…

def calculate
\$m_counter = 0
\$total = @balance

``````while @balance > 0
\$m_counter += 1
remaining_interest = @balance / 100 * @mpr
``````

…because here you are assuming @balance is float.

Note: 50 / 100 * 1.5 = 0.0

instance with float values, but you really shouldn’t rely on that.
The calculator should work properly with integer values, or you
have a rather difficult to find bug (no error messages but possibly
wrong results).

Regards,
Marcus

BTW. Using global variables (like \$m_counter) is usually frowned upon.
You should use instance variables for those, too.

Ryan D. wrote in post #1125855:

On Oct 27, 2013, at 11:09 , Joel P. [email protected] wrote:

If you’re using IRB you’ll get “nil” as a return value when you perform
certain actions like creating a method. This is normal, it just shows
you that nothing is returned.

Wrong. Nil is a value just like everything else. Something was returned:
nil.

Fair point.
In Ruby 2.1 you get a symbol back when you define a method!

Ryan D. wrote in post #1125856:

On Oct 27, 2013, at 09:19 , Greg H. [email protected] wrote:

`````` puts "#{\$m_counter.to_s.ljust(7)} #{@payment.to_s.ljust(12)}
``````

#{interest_paid.to_s.ljust(17)} #{principal.to_s.ljust(21)}
#{@balance.to_s.ljust(1)}"

vs:

puts “%-7d %8.2f %8.2f %8.2f %8.2f” % [\$m_counter, @payment,
interest_paid, principal, @balance]

Wow… didn’t know that.
Could you explain it how it works?

Robert K. wrote in post #1125859:

On Sun, Oct 27, 2013 at 8:03 PM, Joel P. [email protected]
wrote:

FYI for your purposes, “gets.chomp.to_f” is the same as “gets.to_f”.

Even better Float(gets) returns a float and throws if the input is not
a floating point number:

That way you avoid converting invalid input to 0.0.

Kind regards

robert

Thank you! Didn’t know that neither. I’m learning a lot here.
I don’t need the .chomp? Isn’t it so it doesn’t save the enter pressed
after it? :s

On Sun, Oct 27, 2013 at 8:03 PM, Joel P. [email protected]
wrote:

FYI for your purposes, “gets.chomp.to_f” is the same as “gets.to_f”.

Even better Float(gets) returns a float and throws if the input is not
a floating point number:

irb(main):001:0> gets.to_f
1
=> 1.0
irb(main):002:0> gets.to_f
foo
=> 0.0
irb(main):003:0> Float(gets)
1
=> 1.0
irb(main):004:0> Float(gets)
foo
ArgumentError: invalid value for Float(): “foo\n”
from (irb):4:in `Float' from (irb):4 from /usr/bin/irb:12:in`

That way you avoid converting invalid input to 0.0.

Kind regards

robert

On Mon, Oct 28, 2013 at 7:52 PM, Calvin Bornhofen
[email protected] wrote:

On 28.10.2013 19:36, Greg H. wrote:

Wow… didn’t know that. Could you explain it how it works?

the method at work here is #% which formats the receiver by substituting the
placeholders with the arguments it gets. You can read about all formatting
options over in the docs of Kernel#sprintf (String#% uses the same rules):
http://www.ruby-doc.org/core-2.0.0/Kernel.html#method-i-sprintf

Frankly, before I write

puts “%-7d %8.2f %8.2f %8.2f %8.2f” % [\$m_counter, @payment,
interest_paid, principal, @balance]

I’d write

printf “%-7d %8.2f %8.2f %8.2f %8.2f”, \$m_counter, @payment,
interest_paid, principal, @balance

anytime. Much more straightforward. IMHO String#% is best used with a
single argument. As soon as you start having multiple values you need
an explicit Array as show above. But then one can also use (s)printf.

Kind regards

robert

Hello,

On 28.10.2013 19:36, Greg H. wrote:

Wow… didn’t know that. Could you explain it how it works?

the method at work here is #% which formats the receiver by substituting
the placeholders with the arguments it gets. You can read about all
formatting options over in the docs of Kernel#sprintf (String#% uses the
same rules):
http://www.ruby-doc.org/core-2.0.0/Kernel.html#method-i-sprintf

Regards,
Calvin

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.