Asterisks in front of array names in Groovy? - groovy

I'm a bit new to Groovy, so I'm sure this is one of those extremely obvious things...but it's difficult to search for via Google.
In other languages, asterisks tend to represent pointers. However, in this snippet of Groovy code:
byte[] combineArrays(foo, bar, int start) {
[*foo[0..<start], *bar, *foo[start..<foo.size()]]
}
I can only imagine that that's not the case. I mean, pointers? Groovy?
I'm assuming that this code intends to pass the members of foo and bar as opposed to a multidimensional array. So what exactly do the asterisks mean?
Thanks a lot for your help.

When used like this, the * operator spreads a List or Array into a list of arguments. That didn't help at all, did it? How about an example instead? Say we have this function:
def add(Number a, Number b) {
return a + b
}
And this List
def args = [1, 2]
We shouldn't do this:
add(args)
because the function expects two numeric arguments. But we can do this:
add(*args)
because the * operator converts the List of 2 elements into 2 arguments. You can use this operator with Lists and Arrays.

Related

Why does Python `f-string` + inline for loop create a generator when they're passed as parameter?

I found this example on the internet
def format_attributes(**attributes):
"""Return a string of comma-separated key-value pairs."""
return ", ".join(
f"{param}: {value}"
for param, value in attributes.items()
)
The syntax of the param passed to the join function caught my attention because it's sort of unusual. But it works
Doing some local testing with a minimum codebase I discovered that in:
def foo(res):
return res
print(foo(f"{s}" for s in ["bar"]))
foo's syntax is valid and res ends up being a generator. However, if I try f"{s}" for s in ["bar"] standalone (no function in between), the expression just throws a SyntaxError: invalid syntax.
How come the f-string + for loop is valid and gets converted into a generator? What's happening under the hood when invoking foo function?
These other questions uses the same syntax:
f-strings formatter including for-loop or if conditions
https://stackoverflow.com/a/54734702/5745962
But I found no comment explaining why this happens
The looping construct you're using is a generator expression. To write one as a stand-alone expression, you need to add parentheses around it:
genexp = (f"{s}" for s in ["bar"])
If the generator expression is the only argument to a function, you don't need double parentheses (but you do if there are other separate arguments). Contrast:
s = sum(i % 2 for i in some_sequence) # count of odd elements, no extra parentheses needed
vs:
print(*(i for i in some_sequence if i % 2), sep=",") # print odds, parens are needed this time
There's nothing special about f-string used in the generator expression in your code, any expression works the same way.
These are examples of generator expressions and don't necessarily have anything specific to f-strings or which functions you use with them.
e.g.
>>> x = [1, 2, 3, 4]
>>> sum(i%2==0 for i in x)
2
The example counts the number of even integers in the list.
You can read more about them here: https://dbader.org/blog/python-generator-expressions
The f-string has nothing to do with it.
Although a generator expression generally requires parentheses:
some_gen = (f"{s}" for s in ["bar"])
print(foo(some_gen))
the parentheses can be omitted when the generator expression is the only argument to a function call:
# These two calls are equivalent.
foo((f"{s}" for s in ["bar"]))
foo( f"{s}" for s in ["bar"] )

what is the use of * in print(*a) where 'a' is a list in python

I am a python newbie. I saw a code which had * inside a print function // print(*a) // in which 'a' was a list. I know * is multiplication operator in python, but don't know what's it in a list
(If you don't know about the variable number of argument methods, leave this topic and learn this after that)
Unpacking elements in list
Consider new_list = [1, 2, 3]. Now assume you have a function called addNum(*arguments) that expects 'n' number of arguments at different instances.
case 1:
Consider calling our function with one parameter in the list. How will you call it? Will you do it by addNum(new_list[0])?
Cool! No problem.
case 2: Now consider calling our function with two parameters in the list. How will you call it? Will you do it by addNum(new_list[0], new_list[1])?
Seems tricky!!
Case 3: Now consider calling our function with all three parameters in the list. Will you call it by addNum(new_list[0], new_list[1], new_list[2])? Instead what if you can split the values like this with an operator?
Yes! addNum(new_list[0], new_list[1], new_list[2]) <=> addNum(*new_list)
Similarly, addNum(new_list[0], new_list[1]) <=> addNum(*new_list[:2])
Also, addNum(new_list[0]) <=> addNum(*new_list[:1])
By using this operator, you could achieve this!!
It'd print all items without the need of looping over the list. The * operator used here unpacks all items from the list.
a = [1,2,3]
print(a)
# [1,2,3]
print(*a)
# 1 2 3
print(*a,sep=",")
# 1,2,3

On a dataset made up of dictionaries, how do I multiply the elements of each dictionary with Python'

I started coding in Python 4 days ago, so I'm a complete newbie. I have a dataset that comprises an undefined number of dictionaries. Each dictionary is the x and y of a point in the coordinates.
I'm trying to compute the summatory of xy by nesting the loop that multiplies xy within the loop that sums the products.
However I haven't been able to figure out how to multiply the values for the two keys in each dictionary (so far I only got to multiply all the x*y)
So far I've got this:
If my data set were to be d= [{'x':0, 'y':0}, {'x':1, 'y':1}, {'x':2, 'y':3}]
I've got the code for the function that calculates the product of each pair of x and y:
def product_xy (product_x_per_y):
prod_xy =[]
n = 0
for i in range (len(d)):
result = d[n]['x']*d[n]['y']
prod_xy.append(result)
n+1
return prod_xy
I also have the function to add up the elements of a list (like prod_xy):
def total_xy_prod (sum_prod):
all = 0
for s in sum_prod:
all+= s
return all
I've been trying to find a way to nest this two functions so that I can iterate through the multiplication of each x*y and then add up all the products.
Make sure your code works as expected
First, your functions have a few mistakes. For example, in product_xy, you assign n=0, and later do n + 1; you probably meant to do n += 1 instead of n + 1. But n is also completely unnecessary; you can simply use the i from the range iteration to replace n like so: result = d[i]['x']*d[i]['y']
Nesting these two functions: part 1
To answer your question, it's fairly straightforward to get the sum of the products of the elements from your current code:
coord_sum = total_xy_prod(product_xy(d))
Nesting these two functions: part 2
However, there is a much shorter and more efficient way to tackle this problem. For one, Python provides the built-in function sum() to sum the elements of a list (and other iterables), so there's no need create total_xy_prod. Our code could at this point read as follows:
coord_sum = sum(product_xy(d))
But product_xy is also unnecessarily long and inefficient, and we could also replace it entirely with a shorter expression. In this case, the shortening comes from generator expressions, which are basically compact for-loops. The Python docs give some of the basic details of how the syntax works at list comprehensions, which are distinct, but closely related to generator expressions. For the purposes of answering this question, I will simply present the final, most simplified form of your desired result:
coord_sum = sum(e['x'] * e['y'] for e in d)
Here, the generator expression iterates through every element in d (using for e in d), multiplies the numbers stored in the dictionary keys 'x' and 'y' of each element (using e['x'] * e['y']), and then sums each of those products from the entire sequence.
There is also some documentation on generator expressions, but it's a bit technical, so it's probably not approachable for the Python beginner.

What is closure and why to use it?

What is closure in groovy?
Why we use this closure?
Are you asking about Closure annotation parameters?
[...
An interesting feature of annotations in Groovy is that you can use a closure as an annotation value. Therefore annotations may be used with a wide variety of expressions and still have IDE support. For example, imagine a framework where you want to execute some methods based on environmental constraints like the JDK version or the OS. One could write the following code:
class Tasks {
Set result = []
void alwaysExecuted() {
result << 1
}
#OnlyIf({ jdk>=6 })
void supportedOnlyInJDK6() {
result << 'JDK 6'
}
#OnlyIf({ jdk>=7 && windows })
void requiresJDK7AndWindows() {
result << 'JDK 7 Windows'
}
}
...]
Source:http://docs.groovy-lang.org/
Closures are a powerful concept with which you can implement a variety of things and which enable specifying DSLs. They are sort of like Java ( lambdas, but more powerful and versatile. You dont need to use closures, but they can make many things easier.
Since you didnt really specify a concrete question, I'll just point you to the startegy pattern example in the groovy docs:
http://docs.groovy-lang.org/latest/html/documentation/#_strategy_pattern
Think of the closure as an executable unit on its own, like a method or function, except that you can pass it around like a variable, but can do a lot of things that you would normally do with a class, for example.
An example: You have a list of numbers and you either want to add +1 to each number, or you want to double each number, so you say
def nums = [1,2,3,4,5]
def plusone = { item ->
item + 1
}
def doubler = { item ->
item * 2
}
println nums.collect(plusone)
println nums.collect(doubler)
This will print out
[2, 3, 4, 5, 6]
[2, 4, 6, 8, 10]
So what you achieved is that you separated the function, the 'what to do' from the object that you did it on. Your closures separate an action that can be passed around and used by other methods, that are compatible with the closure's input and output.
What we did in the example is that we had a list of numbers and we passed each of them to a closure that did something with it. Either added +1 or doubled the value, and collected them into another list.
And this logic opens up a whole lot of possibilities to solve problems smarter, cleaner, and write code that represents the problem better.

Groovy DSL: creating dynamic closures from Strings

There are some other questions on here that are similar but sufficiently different that I need to pose this as a fresh question:
I have created an empty class, lets call it Test. It doesn't have any properties or methods. I then iterate through a map of key/value pairs, dynamically creating properties named for the key and containing the value... like so:
def langMap = [:]
langMap.put("Zero",0)
langMap.put("One",1)
langMap.put("Two",2)
langMap.put("Three",3)
langMap.put("Four",4)
langMap.put("Five",5)
langMap.put("Six",6)
langMap.put("Seven",7)
langMap.put("Eight",8)
langMap.put("Nine",9)
langMap.each { key,val ->
Test.metaClass."${key}" = val
}
Now I can access these from a new method created like this:
Test.metaClass.twoPlusThree = { return Two + Three }
println test.twoPlusThree()
What I would like to do though, is dynamically load a set of instructions from a String, like "Two + Three", create a method on the fly to evaluate the result, and then iteratively repeat this process for however many strings containing expressions that I happen to have.
Questions:
a) First off, is there simply a better and more elegant way to do this (Based on the info I have given) ?
b) Assuming this path is viable, what is the syntax to dynamically construct this closure from a string, where the string references variable names valid only within a method on this class?
Thanks!
I think the correct answer depends on what you're actually trying to do. Can the input string be a more complicated expression, like '(Two + Six) / Four'?
If you want to allow more complex expressions, you may want to directly evaluate the string as a Groovy expression. Inside the GroovyConsole or a Groovy script, you can directly call evaluate, which will evaluate an expression in the context of that script:
def numNames = 'Zero One Two Three Four Five Six Seven Eight Nine'.split()
// Add each numer name as a property to the script.
numNames.eachWithIndex { name, i ->
this[name] = i
}
println evaluate('(Two + Six) / Four') // -> 2
If you are not in one of those script-friendly worlds, you can use the GroovyShell class:
def numNames = 'Zero One Two Three Four Five Six Seven Eight Nine'.split()
def langMap = [:]
numNames.eachWithIndex { name, i -> langMap[name] = i }
def shell = new GroovyShell(langMap as Binding)
println shell.evaluate('(Two + Six) / Four') // -> 2
But, be aware that using eval is very risky. If the input string is user-generated, i would not recommend you going this way; the user could input something like "rm -rf /".execute(), and, depending on the privileges of the script, erase everything from wherever that script is executed. You may first validate that the input string is "safe" (maybe checking it only contains known operators, whitespaces, parentheses and number names) but i don't know if that's safe enough.
Another alternative is defining your own mini-language for those expressions and then parsing them using something like ANTLR. But, again, this really depends on what you're trying to accomplish.

Resources