How to fix ActionView::Template::Error (Infinity) in Rails? - ruby-on-rails

I'm noticing a strange error in my production application logs:
ActionView::Template::Error (Infinity): /path/to/page/with/problem
/myapp/shared/bundled_gems/ruby/1.9.1/gems/activesupport-3.0.20/lib/active_support/core_ext/float/rounding.rb:16:in `round'
/myapp/shared/bundled_gems/ruby/1.9.1/gems/activesupport-3.0.20/lib/active_support/core_ext/float/rounding.rb:16:in `round'
/myapp/shared/bundled_gems/ruby/1.9.1/gems/activesupport-3.0.20/lib/active_support/core_ext/float/rounding.rb:14:in `round'
/myapp/current/path/to/file/with/problem.rb:106:in `my_buggy_method'
In the code there is something like this:
def my_buggy_method
(number1 - number2).round(2)
end
I don't have any insight as to what numbers are triggering this error. How can I refactor my code to avoid this error?
Update: I managed to start up a Rails console in production and track down the values that are being used in the method above:
number1 == Infinity
number2 == 0
Update: Upon further investigation, number1 is returning Infinity because of division by zero:
number1 == 113 / 0.0
Now that I know where this Infinity is coming from, I will add a check to make sure I can never divide by zero.

The cause of this error was due to trying to round or display Infinity. I did not expect this number, so I have added extra checks to make sure that I don't create Infinity by dividing by zero.

Related

Some lines ending with ";1" in Rails legacy code

Hey Stack Overflow fellows,
I need your help on this one. For a few months now I'm dealing with Ruby on Rails application that is mostly Legacy. Today, I noticed the weirdest thing about the codebase. Some files, not many but the significant ones, contain a few lines of code that would end up with ; 1. Like for example: Users.find(id); 1. Occurrence of those suffixes does not create any form of the pattern. Sometimes is ; 1 appears after puts or after expression that will always return value e.g. nil || 'default_value'; 1.
Does it make any sense to use the suffix? Is there any reason behind this? Maybe there used to be a tool that worked with Ruby code and ; 1 was form of annotation. I would gladly remove the suffix but I want to make sure that it's 100% safe.
Here is a code sample from the project added in the same commit:
times = events.map{|x| [x.time, x.time_from_impression_id]};1
times = times.map{|x| (x.first - x.last) / 1.day}.sort;1
time_to_event_success = times[(times.length.to_f * 0.95).to_i]
events = events.select{|e| e.time_from_impression_id < time_to_event_success.days.ago};1
Semi-colons in ruby terminate statements in the same manner as a line break. The ; 1 really isn't doing anything useful.
Logically the code you posted is equivalent to:
times = events.map{|x| [x.time, x.time_from_impression_id]}
1
times = times.map{|x| (x.first - x.last) / 1.day}.sort
1
time_to_event_success = times[(times.length.to_f * 0.95).to_i]
events = events.select{|e| e.time_from_impression_id <
time_to_event_success.days.ago}
1
The only thing I can think of is that if someone was testing the code out in IRB adding the ; 1 to the end of a line would prevent the return value of the previous statement from echoing. That or they didn't quite understand how implicit return and truthy and falsy values work in ruby.

Finding the number of digits in a number restricted number of tools since I am a Python beginner

def digits(n):
total=0
for i in range(0,n):
if n/(10**(i))<1 and n/(10**(i-1))=>1:
total+=i
else:
total+=0
return total
I want to find the number of digits in 13 so I do the below
print digits(13)
it gives me $\0$ for every number I input into the function.
there's nothing wrong with what I've written as far as I can see:
if a number has say 4 digits say 1234 then dividing by 10^4 will make it less than 1: 0.1234 and dividing by 10^3 will make it 1.234
and by 10^3 will make it 1.234>1. when i satisfies BOTH conditions you know you have the correct number of digits.
what's failing here? Please can you advise me on the specific method I've tried
and not a different one?
Remember for every n there can only be one i which satisfies that condition.
so when you add i to the total there will only be i added so total returning total will give you i
your loop makes no sense at all. It goes from 0 to exact number - not what you want.
It looks like python, so grab a solution that uses string:
def digits(n):
return len(str(int(n))) # make sure that it's integer, than conver to string and return number of characters == number of digits
EDIT:
If you REALLY want to use a loop to count number of digits, you can do this this way:
def digits(n):
i = 0
while (n > 1):
n = n / 10
++i
return i
EDIT2:
since you really want to make your solution work, here is your problem. Provided, that you call your function like digits(5), 5 is of type integer, so your division is integer-based. That means, that 6/100 = 0, not 0.06.
def digits(n):
for i in range(0,n):
if n/float(10**(i))<1 and n/float(10**(i-1))=>1:
return i # we don't need to check anything else, this is the solution
return null # we don't the answer. This should not happen, but still, nice to put it here. Throwing an exception would be even better
I fixed it. Thanks for your input though :)
def digits(n):
for i in range(0,n):
if n/(10**(i))<1 and n/(10**(i-1))>=1:
return i

Getting Syntaxerror : invalid syntax with print

Testing out first time in Idle
def string_length(str1):
count = 0
for char in str1:
count += 1
return count
print(string_length("books"))
keep getting Syntaxerror : invalid syntax. I saw that print needs print () with python 3, i have already done. Not sure is it that i did not install Idle correctly
instead of creating a function to count the number of characters, why don't you use the defined function. like
print(len("book"))
it gives the output as 4.

What's up with the weird breakpoint exception in Swift?

I'm trying to make a path (CGMutablePath) to be used for a shape node in SpriteKit (SKShapeNode). I'm running my code and it stops and says EXC_BREAKPOINT as if there's a breakpoint in the compiler, when there isn't one. Below is a screenshot of what I have.
As you can see, I have no breakpoint set in the compiler. It just tends to stop at line 31. There's nothing in the logs that give a reason for this crash, if there were one to begin with.
I'm used to Objective-C stopping in main.m with Thread 1: SIGABRT and an NSException in the log, but this just makes no sense. Can someone please explain what's wrong?
EDIT: here are more screenshots to prove I have no breakpoints set. When I get an exception, it simply throws a breakpoint.
That exception happens because arc4random() returns UInt32 and you are subtracting a value of that, which possibly causes a negative value, which is not representable as an unsigned integer.
To fix this you may want to cast the expression to Int32 before subtracting:
var y = CGFloat(self.size.height / 3) + CGFloat((Int32)(arc4random() % 100) - 50)
Regarding the x value above - you create CGFloat and only subtract after that and therefore not encounter the above situation. Therefore a different fix would be the following
var y = CGFloat(self.size.height / 3) + CGFloat(arc4random() % 100) - 50
You basically have to ensure that at the point where you subtract something you have no unsigned type present.
The annoying thing about this is that the compiler does not warn you and the code actually works sometimes, every time when arc4random returns something larger than 50 and will therefore not drift into the negative values...
Incorporating the feedback and suggestion that you should not use arc4random % something the best solution would be to use arc4random_uniform.
arc4random % something will not yield a proper distribution of the random values, while arc4random_uniform(something) does - this has already been discussed on SO before.
A final note: you probably should choose 101 as upper bound instead of 100 because both arc4random as well as arc4random_uniform produce a value between 0 and (upper-1), e.g. 0 and 99. If you subtract 50 you get a value between -50 and +49. Choosing 101 will yield the desired range of -50 to +50.
var y = CGFloat(self.size.height / 3) + CGFloat(arc4random_uniform(101)) - 50

BigDecimal to Currency with -0.0

I am working on reports for a website and I am currently thinking of what would be the best way to handle BigDecimal -0.0's.
The database I'm working with has a lot of them. When these -0.0's are put through number_to_currency(), I get "$-0.00". My format for negative numbers is actually "-$x.xx", so note that number_to_currency is not formatting it as a negative number (otherwise there would also be a negative sign in front of the dollar sign), but for some reason the negative sign is being translated along with the 0.
Right now my solution is to do this every time I get an amount from the database:
amount *= -1 if amount == 0 && amount.sign == -1
This changes the -0.0 to a 0.0. It's simple enough, but I can't help but wonder if there is a better solution, or something on BigDecimals or number_to_currency to handle this situation that I'm just not finding.
That is so because the number is converted into a string to be displayed. And:
# to_d converts to BigDecimal, just FYI
"-0".to_d.to_s #=> "-0.0"
Therefore you will have to make it a 0 yourself. But the sign-checks are redundant - a simple comparison with 0 will do the trick:
bdn = "-0".to_d # or BigDecimal.new("-0")
value = bdn.zero? ? 0 : bdn
number_to_currency(value, other_options)
However, you wouldn't want to manually add this check everywhere you're calling number_to_currency. It would be more convenient to create your own modified_number_to_currency method, in your ApplicationHelper, like so:
def modified_number_to_currency( number, options )
value = number.zero? ? 0 : number
number_to_currency(value, options)
end
And then use modified_number_to_currency instead of number_to_currency.
Alternatively, you could overwrite number_to_currency and have it call super in the end. That might also work but I'm not 100% certain.
Coming to your check specifically:
amount *= -1 if amount == 0 && amount.sign == -1
It should simply be:
amount = 0.to_d if amount.zero? # the to_d might or might not be required

Resources