Forum: Ruby nill output message (classes)

02ace4696e2e69eefd1578cacd946ceb?d=identicon&s=25 Greg Hajdu (vori)
on 2013-10-27 17:19
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

puts "Please tell me your credit card balance."
balance = gets.chomp.to_f

puts "Please enter your APR!"
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
14b5582046b4e7b24ab69b7886a35868?d=identicon&s=25 Joel Pearson (virtuoso)
on 2013-10-27 19:09
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?
02ace4696e2e69eefd1578cacd946ceb?d=identicon&s=25 Greg Hajdu (vori)
on 2013-10-27 19:17
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!

Please tell me your credit card balance.
50
Please enter your APR!
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
14b5582046b4e7b24ab69b7886a35868?d=identicon&s=25 Joel Pearson (virtuoso)
on 2013-10-27 19:51
The last action in the method "calculate" is "puts". This returns nil.
Abdb670e1c130f96f947a94d03c02efa?d=identicon&s=25 Eric Christopherson (echristopherson)
on 2013-10-27 20:00
(Received via mailing list)
On Sun, Oct 27, 2013 at 1:51 PM, Joel Pearson <lists@ruby-forum.com>
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.
14b5582046b4e7b24ab69b7886a35868?d=identicon&s=25 Joel Pearson (virtuoso)
on 2013-10-27 20:03
FYI for your purposes, "gets.chomp.to_f" is the same as "gets.to_f".
15000f55138ae94b0f362ed7c625461a?d=identicon&s=25 unknown (Guest)
on 2013-10-28 10:30
(Received via mailing list)
Am 27.10.2013 17:19, schrieb Greg Hajdu:
>   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

In fact, in your program you correctly initialize your calculator
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.
5a837592409354297424994e8d62f722?d=identicon&s=25 Ryan Davis (Guest)
on 2013-10-28 11:09
(Received via mailing list)
On Oct 27, 2013, at 11:09 , Joel Pearson <lists@ruby-forum.com> 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.
5a837592409354297424994e8d62f722?d=identicon&s=25 Ryan Davis (Guest)
on 2013-10-28 11:14
(Received via mailing list)
On Oct 27, 2013, at 09:19 , Greg Hajdu <lists@ruby-forum.com> 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]
14b5582046b4e7b24ab69b7886a35868?d=identicon&s=25 Joel Pearson (virtuoso)
on 2013-10-28 11:24
Ryan Davis wrote in post #1125855:
> On Oct 27, 2013, at 11:09 , Joel Pearson <lists@ruby-forum.com> 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!
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2013-10-28 12:02
(Received via mailing list)
On Sun, Oct 27, 2013 at 8:03 PM, Joel Pearson <lists@ruby-forum.com>
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 `<main>'

That way you avoid converting invalid input to 0.0.

Kind regards

robert
02ace4696e2e69eefd1578cacd946ceb?d=identicon&s=25 Greg Hajdu (vori)
on 2013-10-28 19:36
Ryan Davis wrote in post #1125856:
> On Oct 27, 2013, at 09:19 , Greg Hajdu <lists@ruby-forum.com> 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. :D
Could you explain it how it works? :)
02ace4696e2e69eefd1578cacd946ceb?d=identicon&s=25 Greg Hajdu (vori)
on 2013-10-28 19:38
Robert Klemme wrote in post #1125859:
> On Sun, Oct 27, 2013 at 8:03 PM, Joel Pearson <lists@ruby-forum.com>
> 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. :D
I don't need the .chomp? Isn't it so it doesn't save the enter pressed
after it? :s
45441e46d19d428be152ecb81883044a?d=identicon&s=25 Calvin B. (calvin_b)
on 2013-10-28 19:53
(Received via mailing list)
Hello,

On 28.10.2013 19:36, Greg Hajdu wrote:
> Wow.. didn't know that. :D 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#met...

Regards,
Calvin
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2013-10-29 00:06
(Received via mailing list)
On Mon, Oct 28, 2013 at 7:52 PM, Calvin Bornhofen
<calvin.bornhofen@web.de> wrote:
> On 28.10.2013 19:36, Greg Hajdu wrote:
>>
>> Wow.. didn't know that. :D 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#met...

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
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.