Motivation
Say we have a number of randomly sized numbers, generated with something like:
values = (0...10).map { |_| rand(1_000_000) }
We can determine the width required to display each of these numbers comfortably with the following:
width = values
.map { |x| Math.log10(x).to_i + 1 }
.max
and use this width in Kernel#printf like so:
values.each { |x| printf("%*d\n", width, x) }
taking advantage of the * flag to:
Use the next argument as the field width.
as per Kernel#format.
Issue
If we wanted to make use of both named references and the * flag inside the format string, we then start to run into issues. Attempting the following:
printf("%<value>*d\n", width, value: x)
raises the following error:
main.rb:7:in `printf': one hash required (ArgumentError)
and flipping the order of the arguments to:
printf("%<value>*d\n", value: x, width)
raises the following error:
main.rb:7: syntax error, unexpected ')', expecting =>
...%<value>*d\n", value: x, width) }
As a test, omitting width entirely (with no expectation of success):
printf("%<value>*d\n", value: x)
gives the following error:
main.rb:7:in `printf': unnumbered(1) mixed with named (ArgumentError)
Is it categorically currently not possible to use named references with the * flag in Ruby string formatting?
Related
The "GlobalScope" class defines many fundamental enums like the Error enum.
I'm trying to produce meaningful logs when an error occurs. However printing a value of type Error only prints the integer, which is not very helpful.
The Godot documentation on enums indicates that looking up the value should work in a dictionary like fashion. However, trying to access Error[error_value] errors with:
The identifier "Error" isn't declared in the current scope.
How can I convert such enum values to string?
In the documentation you referenced, it explains that enums basically just create a bunch of constants:
enum {TILE_BRICK, TILE_FLOOR, TILE_SPIKE, TILE_TELEPORT}
# Is the same as:
const TILE_BRICK = 0
const TILE_FLOOR = 1
const TILE_SPIKE = 2
const TILE_TELEPORT = 3
However, the names of the identifiers of these constants only exist to make it easier for humans to read the code. They are replaced on runtime with something the machine can use, and are inaccessible later. If I want to print an identifier's name, I have to do so manually:
# Manually print TILE_FLOOR's name as a string, then its value.
print("The value of TILE_FLOOR is ", TILE_FLOOR)
So if your goal is to have descriptive error output, you should do so in a similar way, perhaps like so:
if unexpected_bug_found:
# Manually print the error description, then actually return the value.
print("ERR_BUG: There was a unexpected bug!")
return ERR_BUG
Now the relationship with dictionaries is that dictionaries can be made to act like enumerations, not the other way around. Enumerations are limited to be a list of identifiers with integer assignments, which dictionaries can do too. But they can also do other cool things, like have identifiers that are strings, which I believe you may have been thinking of:
const MyDict = {
NORMAL_KEY = 0,
'STRING_KEY' : 1, # uses a colon instead of equals sign
}
func _ready():
print("MyDict.NORMAL_KEY is ", MyDict.NORMAL_KEY) # valid
print("MyDict.STRING_KEY is ", MyDict.STRING_KEY) # valid
print("MyDict[NORMAL_KEY] is ", MyDict[NORMAL_KEY]) # INVALID
print("MyDict['STRING_KEY'] is ", MyDict['STRING_KEY']) # valid
# Dictionary['KEY'] only works if the key is a string.
This is useful in its own way, but even in this scenario, we assume to already have the string matching the identifier name explicitly in hand, meaning we may as well print that string manually as in the first example.
The naive approach I done for me, in a Singleton (in fact in a file that contain a lot of static funcs, referenced by a class_name)
static func get_error(global_error_constant:int) -> String:
var info := Engine.get_version_info()
var version := "%s.%s" % [info.major, info.minor]
var default := ["OK","FAILED","ERR_UNAVAILABLE","ERR_UNCONFIGURED","ERR_UNAUTHORIZED","ERR_PARAMETER_RANGE_ERROR","ERR_OUT_OF_MEMORY","ERR_FILE_NOT_FOUND","ERR_FILE_BAD_DRIVE","ERR_FILE_BAD_PATH","ERR_FILE_NO_PERMISSION","ERR_FILE_ALREADY_IN_USE","ERR_FILE_CANT_OPEN","ERR_FILE_CANT_WRITE","ERR_FILE_CANT_READ","ERR_FILE_UNRECOGNIZED","ERR_FILE_CORRUPT","ERR_FILE_MISSING_DEPENDENCIES","ERR_FILE_EOF","ERR_CANT_OPEN","ERR_CANT_CREATE","ERR_QUERY_FAILED","ERR_ALREADY_IN_USE","ERR_LOCKED","ERR_TIMEOUT","ERR_CANT_CONNECT","ERR_CANT_RESOLVE","ERR_CONNECTION_ERROR","ERR_CANT_ACQUIRE_RESOURCE","ERR_CANT_FORK","ERR_INVALID_DATA","ERR_INVALID_PARAMETER","ERR_ALREADY_EXISTS","ERR_DOES_NOT_EXIST","ERR_DATABASE_CANT_READ","ERR_DATABASE_CANT_WRITE","ERR_COMPILATION_FAILED","ERR_METHOD_NOT_FOUND","ERR_LINK_FAILED","ERR_SCRIPT_FAILED","ERR_CYCLIC_LINK","ERR_INVALID_DECLARATION","ERR_DUPLICATE_SYMBOL","ERR_PARSE_ERROR","ERR_BUSY","ERR_SKIP","ERR_HELP","ERR_BUG","ERR_PRINTER_ON_FIR"]
match version:
"3.4":
return default[global_error_constant]
# Regexp to use on #GlobalScope documentation
# \s+=\s+.+ replace by nothing
# (\w+)\s+ replace by "$1", (with quotes and comma)
printerr("you must check and add %s version in get_error()" % version)
return default[global_error_constant]
So print(MyClass.get_error(err)), or assert(!err, MyClass.get_error(err)) is handy
For non globals I made this, though it was not your question, it is highly related.
It would be useful to be able to access to #GlobalScope and #GDScript, maybe due a memory cost ?
static func get_enum_flags(_class:String, _enum:String, flags:int) -> PoolStringArray:
var ret := PoolStringArray()
var enum_flags := ClassDB.class_get_enum_constants(_class, _enum)
for i in enum_flags.size():
if (1 << i) & flags:
ret.append(enum_flags[i])
return ret
static func get_constant_or_enum(_class:String, number:int, _enum:="") -> String:
if _enum:
return ClassDB.class_get_enum_constants(_class, _enum)[number]
return ClassDB.class_get_integer_constant_list(_class)[number]
This question already has answers here:
What are these three dots in React doing?
(23 answers)
Closed 4 years ago.
I'm putting my hands into reason-react.
In the following code :
let component = ReasonReact.statelessComponent("Component3");
let make = (~name, _children) => {
...component,
render: self => <input type_="checkbox" />,
};
I don't understand what (...) means on line 3.
When I delete it I get an error message :
The record field component can't be found.
If it's defined in another module or file, bring it into scope by:
- Annotating it with said module name: let baby = {MyModule.age: 3}
- Or specifying its type: let baby: MyModule.person = {age: 3}
The representation is called Spread Syntax. This was introduced in ES6.
Definition and example from MDN Docs. Link at the bottom.
Spread syntax allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers));
// expected output: 6
console.log(sum.apply(null, numbers));
// expected output: 6
More details at : Spread Syntax
I would like to use Iverson bracket (ie. mapping true => 1, false => 0) in the XPath expression.
Example: instead of writing
someNumber+(if(elem1/elem2[#attr='123'])then(1)else(0)))*someOtherNumber
I would like to write (but somehow without the "Iverson")
someNumber+Iverson(elem1/elem2[#attr='123'])*someOtherNumber
The following doesn't work:
someNumber+[elem1/elem2[#attr='123']]*someOtherNumber
Casting to boolean works:
someNumber+boolean(elem1/elem2[#attr='123'])*someOtherNumber
Is there a more simple syntax than "if(...)then(1)else(0)" or "boolean(...)"?
Iverson
Interestingly, in XPath you already use a version of the Iverson bracket syntax with predicates in [#attr='123'] or [#attr], which returns true if its EBV is true. But if it evaluates to a number, it will return the nth item from the sequence.
For the discussion, let's replace your expression elem1/elem2[#attr='123'] with EXPR for brevity, and the rest like:
X + EXPR * Y
Where the idea is to get as close as possible to the Iverson syntax for EXPR.
XPath 2.0
Your expression requires less parentheses:
X + if(EXPR) then 1 else 0 * Y
This can also be written as the following, assuming false-value of EXPR is an empty sequence:
X + (EXPR, 1, 0)[2] * Y
Is there a more simple syntax than "boolean(...)"?
You suggested the boolean(EXPR) function, but as you mentioned in the comments, this will not work, you need to convert it to a number, for instance with:
X + number(boolean(EXPR)) * Y
I think the shortest version in XPath 2.0 is the empty-sequence dismissal approach, but it may not always work, it requires the first item to return the empty sequence.
If you have a validating processor that sets the element as boolean, you can use:
X + number(EXPR) * Y
Or if typed as a number with valid values 0 and 1, just:
EXPR
XPath 3.0
Let's see if with the new XPath 3.0 syntax we can get even simpler:
let $Iv := function($i) { number(boolean($i)) }
return X + $Iv(EXPR) * Y
With XQuery and XSLT, but also XPath, you can declare this variable globally, which changes the expression into:
X + $Yv(EXPR) * Y
But you'll still have to deal with the parentheses, but keep reading...
XPath 3.1
In 3.1, the arrow operator has been introduced, which allows your original example to be written as:
X + EXPR=>boolean()=>number() * Y
Given that we now have a global variable with a function item, we can do:
X + EXPR=>$Iv() * Y
Other approach
Since setting a global variable to an anonymous function is nothing more than creating a function, we can also declare a function in XQuery or XSLT. Something like:
X + EXPR=>i:v() * Y
I am trying to run a granger causality test on two currency pairs but I seem to get this error message in Shell whenever I try and test it. Can anyone please advise?
I am very new to programming and need this to run an analysis for my project. In shell, I am putting -
import ats15
ats15.grangertest('EURUSD', 'EURGBP', 8)
What is going wrong? I have copied the script below.
Thanks in advance.
Heading ##def grangertest(Y,X,maxlag):
"""
Performs a Granger causality test on variables (vectors) Y and X.
The null hypothese is: Does X cause Y ?
Returned value: pvalue, F, df1, df2
"""
# Create linear model involving Y lags only.
n = len(Y)
if n != len(X):
raise ValueError, "grangertest: incompatible Y,X vectors"
M = [ [0] * maxlag for i in range(n-maxlag)]
for i in range(maxlag, n):
for j in range(1, maxlag+1):
M[i-maxlag][j-1] = Y[i-j]
fit = ols(M, Y[maxlag:])
RSSr = fit.RSS
# Create linear model including X lags.
for i in range(maxlag, n):
xlagged = [X[i-j] for j in range(1, maxlag+1)]
M[i-maxlag].extend(xlagged)
fit = ols(M, Y[maxlag:])
RSSu = fit.RSS
df1 = maxlag
df2 = n - 2 * maxlag - 1
F = ((RSSr - RSSu)/df1)/(RSSu/df2)
pvalue = 1.0 - stats.f.cdf(F,df1,df2)
return pvalue, F, df1, df2, RSSr, RSSu
You didn't post the full traceback, but this error message:
TypeError: unsupported operand type(s) for -: 'str' and 'int'
means what it says. There's an operand - -- the subtraction operator -- and it doesn't know how to handle subtracting an integer from a string. Why would strings be involved? Well, you're calling the function with:
ats15.grangertest('EURUSD', 'EURGBP', 8)
and so you're giving grangertest two strings and an integer. But it seems like grangertest expects
def grangertest(Y,X,maxlag):
two sequences (lists, arrays, whatever) of numbers to use as Y and X, not strings. If EURUSD and EURGBP are names you've given to lists beforehand, then you don't need the quotes:
ats15.grangertest(EURUSD, EURGBP, 8)
but if not, then you should pass grangertest the lists under whatever name you've called them.
The input to the grangertest function must be two lists of numbers. grangertest doesn't know anything about currencies, so passing it currency strings won't work.
You have to fetch the exchange rate data somehow so that you can pass it to grangertest. If EURUSD and EURGBP are variables, then you don't put quotes around them when you pass them to a function (e.g. ats15.grangertest(EURUSD, EURGBP, 8)).
In the case of e.g. ddddd, d is the native format for the system, so I can't know exactly how big it will be.
In python I can do:
import struct
print struct.calcsize('ddddd')
Which will return 40.
How do I get this in Ruby?
I haven't found a built-in way to do this, but I've had success with this small function when I know I'm dealing with only numeric formats:
def calculate_size(format)
# Only for numeric formats, String formats will raise a TypeError
elements = 0
format.each_char do |c|
if c =~ /\d/
elements += c.to_i - 1
else
elements += 1
end
end
([ 0 ] * elements).pack(format).length
end
This constructs an array of the proper number of zeros, calls pack() with your format, and returns the length (in bytes). Zeros work in this case because they're convertible to each of the numeric formats (integer, double, float, etc).
I don't know of a shortcut but you can just pack one and ask how long it is:
length_of_five_packed_doubles = 5 * [1.0].pack('d').length
By the way, a ruby array combined with the pack method appears to be functionally equivalent to python's struct module. Ruby pretty much copied perl's pack and put them as methods on the Array class.