Am a little confused about array behaviors in Ruby
Given this;
string = "abcac"
remainder = 1
What will the following function do?
string[0, remainder]
let's try to check documentation for class String. Just google rubydoc string
and https://ruby-doc.org/core-2.4.0/String.html
then look for square brackets:
str[start, length] → new_str or nil
have a nice day and good luck with coding.
Max
Thank you.
I kept researching and found that
The first operand specifies an index(which may be negative), and the second specifies the length(which must be non negative)
[index, length]
Related
The code goes:
def stratified_subsampling(arr, n_strata, n_points, srand)
<<-DOC
The function samples "n_points" points from an array "arr".
It preserves the original distribution of the data. "n_strata"
is the number of strata to devide the values in. Have to find a
trade-off for this value, but I think that as a rule of thumb,
10 bins should be fair enough in most cases.
DOC
vs = arr.sort
...
Rubocop says:
W: Lint/Void: Literal <<-DOC used in void context.
<<-DOC
^^^^^^
I don't understand what that means and how should I fix it.
Thank you!
It means that you have a string literal here that you do absolutely nothing with. Does it need to be a string literal? A comment should serve just fine.
I'm a newbie to Smarty. I want to do a mod operation on an array element in smarty. Following is the code snippet I'm trying to implement:
{if {$que_seq_no}.{$sub_ques_no+1} % 10 == 1}
Could you please help me to correct it? Thanks in Advance.
Answer to question title
The modulo operator is % and has also alternation mod.
For more on recognized qualifiers in smarty reffer to docs: http://www.smarty.net/docsv2/en/language.function.if
Answer to your problem
So as you now know, your modulo operator is correct.
From what I can guess from your syntax, you are probably trying to access value of array by array index.
For accessing array items you have 2 possibilities:
Access by array key - syntax: $arrayVariable.key
Access by array index - syntax: $arrayVariable[index] (index is an int number) So in your case: $que_seq_no[$sub_ques_no+1]
If you are trying to access object property:
it is similar to access by array key, but operator is -> so syntax is: $objectVariable->propertyName
For more on this reffer to smarty docs: http://www.smarty.net/docsv2/en/language.variables.tpl
What probably confused you
I think you got a bit confused by usage of {} (curly braces)
- they are used to wrap the whole smarty expression - so from that it implies that they can't contain any other { or }.
A pretty example taken from smarty docs is:
{if $name == 'Fred' || $name == 'Wilma'}
...
{/if}
You are using acceptable syntax for the mod operation. I am pretty sure you're using incorrect syntax with the variable {$que_seq_no}.{$sub_ques_no+1}. Have you tried $que_seq_no[$sub_ques_no+1]?
I have to search an item in an array and return the value of the next item. Example:
a = ['abc.df','-f','test.h']
i = a.find_index{|x| x=~/-f/}
puts a[i+1]
Is there any better way other than working with index?
A classical functional approach uses no indexes (xs.each_cons(2) -> pairwise combinations of xs):
xs = ['abc.df', '-f', 'test.h']
(xs.each_cons(2).detect { |x, y| x =~ /-f/ } || []).last
#=> "test.h"
Using Enumerable#map_detect simplifies it a litte bit more:
xs.each_cons(2).map_detect { |x, y| y if x =~ /-f/ }
#=> "test.h"
The reason something like array.find{something}.next doesn't exist is that it's an array rather than a linked list. Each item is just it's own value; it doesn't have a concept of "the item after me".
#tokland gives a good solution by iterating over the array with each pair of consecutive items, so that when the first item matches, you have your second item handy. There are strong arguments to be made for the functional style, to be sure. Your version is shorter, though, and I'd argue that yours is also more quickly and easily understood at a glance.
If the issue is that you're using it a lot and want something cleaner and more to the point, then of course you could just add it as a singleton method to a:
def a.find_after(&test)
self[find_index(&test).next]
end
Then
a.find_after{|x| x=~/-f/}
is a clear way to find the next item after the first match.
All of that said, I think #BenjaminCox makes the best point about what appears to be your actual goal. If you're parsing command line options, there are libraries that do that well.
I don't know of a cleaner way to do that specific operation. However, it sure looks like you're trying to parse command-line arguments. If so, I'd recommend using the built-in OptionParser module - it'll save a ton of time and hair-pulling trying to parse them yourself.
This article explains how it works.
Your solution working with indexes is fine, as others have commented. You could use Enumerable#drop_while to get an array from your match on and take the second element of that:
a = ['abc.df','-f','test.h']
f_arg = a.drop_while { |e| e !~ /-f/ }[1]
I want to convert from cents to dollars correctly in Ruby. I will never have to work with fractions of cents.
Is it possible to do this correctly (without floating point errors) without having to use BigDecimal?
E.g., cents to dollars
"99" => "0.99"
"324" => "3.24"
The following seems to work, but is it correct?
(cents.to_i/100.0).to_s
Update: I noticed the line above doesn't work if cents = "10287349283923497624861294712974892742837833".
As Micheal Kohl already answered: Take a look to the money gem.
Example:
require 'money'
Money.use_i18n = false #https://stackoverflow.com/q/31133229/676874
puts Money.new( 99, 'USD')
puts Money.new(324, 'USD')
The following seems to work, but is it correct?
(cents.to_i/100.0).to_s
On the first look, it is ok, but:
cents = '10'
p (cents.to_i/100.0).to_s # -> '0.1'
You don't have 2 digits.
Alternative:
p '%.2f' % (cents.to_i/100.0) # -> '0.10'
You can consider using Rationals as well. However, I am not sure do they get converted to floats when sprintf-ed:
"%.2f" % Rational("324".to_i,100)
#=> "3.24"
"%.2f" % Rational("99".to_i,100)
#=> "0.99"
"%.2f" % Rational("80".to_i,100)
#=> "0.80"
"%.2f" % Rational("12380".to_i,100)
#=> "123.80"
If they're stings already you could use string manipulation and bypass the numeric problems completely:
# There are, of course, all sorts of ways to do this.
def add_decimal(s)
pfx = [ '0.00', '0.0', '0.' ]
if(pfx[s.length])
s = pfx[s.length] + s
else
s = s.dup
s[-2, 0] = '.'
end
s
end
add_decimal('') # "0.00"
add_decimal('1') # "0.01"
add_decimal('12') # "0.12"
add_decimal('123') # "1.23"
add_decimal('1234') # "12.34"
add_decimal('12345') # "123.45"
No precision issues, no floating point, no bignums, no Rational, nothing tricky, nothing clever. Some simple modifications would be needed to deal with negative values but that will be as simple as what's already there.
Personally I wouldn't try to re-invent this specific wheel and go with the money gem. From the docs (emphasis added):
Features
Provides a Money class which encapsulates all information about an
certain amount of money, such as its value and its currency.
Provides a Money::Currency class which encapsulates all information about a
monetary unit.
Represents monetary values as integers, in cents. This
avoids floating point rounding errors.
Represents currency as
Money::Currency instances providing an high level of flexibility.
Provides APIs for exchanging money from one currency to another.
Has
the ability to parse a money and currency strings into the
corresponding Money/Currency object.
Here's a one-line method that also simply uses string manipulation thereby completely bypassing the numeric issues:
cents.rjust(3, "0").insert(-3, ".")
These answers are fairly old, so I wanted the next person to know there's an easier way (if you're using Rails).
ActiveSupport::NumberHelper.number_to_currency(111048.fdiv(100))
There's currency and precision options. See Rails documentation
You can use fdiv for this purpose. It returns the floating point result after division of two numbers
-> price.to_i.fdiv(100)
For example: '123'.to_i.fdiv(100) -> 1.23
('1' * N) !~ /^1?$|^(11+?)\1+$/
On the net, I found this piece of Ruby code that works for N >= 0 that determines whether or not N is a prime. From what I can tell, it looks like play with regex but I have no idea how it works. Could someone tell me how it works?
You can find a lengthy explanation of this code here:
http://www.noulakaz.net/weblog/2007/03/18/a-regular-expression-to-check-for-prime-numbers/
This is probably rather off-topic, but in Ruby 1.9, you can do this:
require 'mathn'
38749711234868463.prime?
=> false
require 'prime'
Prime.prime?(4)
# => false
Prime.prime?(5)
# => true
Or:
require 'prime'
Prime.instance.prime?(4)
# => false
Prime.instance.prime?(5)
# => true
See also What is the most brilliant regex you’ve ever used? (and yes, I can confirm that this regexp was originally written by Abigail. I've even heard her explain how it works :)
Greatest Common Divisor (gcd):
/^(1+)\1*=\1+$/.match('1' * x + '=' + '1' * y)[1].length
Both this and the is_prime one works in about the same way. It tries all combinations before giving up.
This one will try to split the first number in even parts, and match the second number with one or more of those parts. If it finds a match it returns the length of the selected part.
Yet another blog with a pretty good explanation: Famous Perl One-Liners Explained (part III)
If the length of a string of 1's is composite, then the string can be decomposed into multiple identical substrings, like 111111 -> 11 11 11
For example, 1111111111, has 10 1's, and it matches (11){5} or (11111){2}, where {2} means repeated 2 times.
111111111, has 9 1's, and it matches (111){3}.
By generalizing the count of 1's and the number in {}, the regexp is
/(1{2,}){2,}/.
However, 1{2,} can also be written as 11+, and (...){2,} can be rewritten as (...)\1+, with backreferences.
The ^1?$ part in the first alternation checks for 0 and 1-cases.