I've been programming in Java for a while and I decided to try and learn Groovy. I'm going through the project euler problems and one the first problem I've already noticed something strange.
class Problem1
{
public static void main(String[] args)
{
def multiple = 1;
for(i in 1..1001)
{
//if it is divisible by three then multiply is
if(i%3 ==0)
{
multiple = multiple * i;
}
if(i%5 ==0)
{
multiple = multiple * i;
}
holder = multiple
}
println(multiple)
}
}
my value to multiple is being set incorrectly. Everything works as expected inside of the loop but when I try to print my value I get 0. It doesn't even print the 1 that I set the variable to initially. I wouldn't expect this to happen in Java. Why does it happen in Groovy? I thought that groovy was supposed to be like Java under the hood.
You're overflowing an integer (as you would in Java also)
Try using a BigInteger by changing
def multiple = 1;
To
def multiple = 1G
Related
Functions in Dart are first-class objects, allowing you to pass them to other objects or functions.
void main() {
var shout = (msg) => ' ${msg.toUpperCase()} ';
print(shout("yo"));
}
This made me wonder if there was a way to modify a function a run time, just like an object, prior to passing it to something else. For example:
Function add(int input) {
return add + 2;
}
If I wanted to make the function a generic addition function, then I would do:
Function add(int input, int increment) {
return add + increment;
}
But then the problem would be that the object I am passing the function to would need to specify the increment. I would like to pass the add function to another object, with the increment specified at run time, and declared within the function body so that the increment cannot be changed by the recipient of the function object.
The answer seems to be to use a lexical closure.
From here: https://dart.dev/guides/language/language-tour#built-in-types
A closure is a function object that has access to variables in its
lexical scope, even when the function is used outside of its original
scope.
Functions can close over variables defined in surrounding scopes. In
the following example, makeAdder() captures the variable addBy.
Wherever the returned function goes, it remembers addBy.
/// Returns a function that adds [addBy] to the
/// function's argument.
Function makeAdder(int addBy) {
return (int i) => addBy + i;
}
void main() {
// Create a function that adds 2.
var add2 = makeAdder(2);
// Create a function that adds 4.
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
In the above cases, we pass 2 or 4 into the makeAdder function. The makeAdder function uses the parameter to create and return a function object that can be passed to other objects.
You most likely don't need to modify a closure, just the ability to create customized closures.
The latter is simple:
int Function(int) makeAdder(int increment) => (int value) => value + increment;
...
foo(makeAdder(1)); // Adds 1.
foo(makeAdder(4)); // Adds 2.
You can't change which variables a closure is referencing, but you can change their values ... if you an access the variable. For local variables, that's actually hard.
Mutating state which makes an existing closure change behavior can sometimes be appropriate, but those functions should be very precise about how they change and where they are being used. For a function like add which is used for its behavior, changing the behavior is rarely a good idea. It's better to replace the closure in the specific places that need to change behavior, and not risk changing the behavior in other places which happen to depend on the same closure. Otherwise it becomes very important to control where the closure actually flows.
If you still want to change the behavior of an existing global, you need to change a variable that it depends on.
Globals are easy:
int increment = 1;
int globalAdder(int value) => value + increment;
...
foo(globalAdd); // Adds 1.
increment = 2;
foo(globalAdd); // Adds 2.
I really can't recommend mutating global variables. It scales rather badly. You have no control over anything.
Another option is to use an instance variable to hold the modifiable value.
class MakeAdder {
int increment = 1;
int instanceAdd(int value) => value + increment;
}
...
var makeAdder = MakeAdder();
var adder = makeAdder.instanceAdd;
...
foo(adder); // Adds 1.
makeAdder.increment = 2;
foo(adder); // Adds 2.
That gives you much more control over who can access the increment variable. You can create multiple independent mutaable adders without them stepping on each other's toes.
To modify a local variable, you need someone to give you access to it, from inside the function where the variable is visible.
int Function(int) makeAdder(void Function(void Function(int)) setIncrementCallback) {
var increment = 1;
setIncrementCallback((v) {
increment = v;
});
return (value) => value + increment;
}
...
void Function(int) setIncrement;
int Function(int) localAdd = makeAdder((inc) { setIncrement = inc; });
...
foo(localAdd); // Adds 1.
setIncrement(2);
foo(localAdd); // Adds 2.
This is one way of passing back a way to modify the local increment variable.
It's almost always far too complicated an approach for what it gives you, I'd go with the instance variable instead.
Often, the instance variable will actually represent something in your model, some state which can meaningfully change, and then it becomes predictable and understandable when and how the state of the entire model changes, including the functions referring to that model.
Using partial function application
You can use a partial function application to bind arguments to functions.
If you have something like:
int add(int input, int increment) => input + increment;
and want to pass it to another function that expects to supply fewer arguments:
int foo(int Function(int input) applyIncrement) => applyIncrement(10);
then you could do:
foo((input) => add(input, 2); // `increment` is fixed to 2
foo((input) => add(input, 4); // `increment` is fixed to 4
Using callable objects
Another approach would be to make a callable object:
class Adder {
int increment = 0;
int call(int input) => input + increment;
}
which could be used with the same foo function above:
var adder = Adder()..increment = 2;
print(foo(adder)); // Prints: 12
adder.increment = 4;
print(foo(adder)); // Prints: 14
I store various formulas in Postgres and I want to use those formulas in my code. It would look something like this:
var amount = 100;
var formula = '5/105'; // normally something I would fetch from Postgres
var total = amount * formula; // should return 4.76
Is there a way to evaluate the string in this manner?
As far as I'm aware, there isn't a formula solver package developed for Dart yet. (If one exists or gets created after this post, we can edit it into the answer.)
EDIT: Mattia in the comments points out the math_expressions package, which looks pretty robust and easy to use.
There is a way to execute arbitrary Dart code as a string, but it has several problems. A] It's very roundabout and convoluted; B] it becomes a massive security issue; and C] it only works if the Dart is compiled in JIT mode (so in Flutter this means it will only work in debug builds, not release builds).
So the answer is that unfortunately, you will have to implement it yourself. The good news is that, for simple 4-function arithmetic, this is pretty straight-forward, and you can follow a tutorial on writing a calculator app like this one to see how it's done.
Of course, if all your formulas only contain two terms with an operator between them like in your example snippet, it becomes even easier. You can do the whole thing in just a few lines of code:
void main() {
final amount = 100;
final formula = '5/105';
final pattern = RegExp(r'(\d+)([\/+*-])(\d+)');
final match = pattern.firstMatch(formula);
final value = process(num.parse(match[1]), match[2], num.parse(match[3]));
final total = amount * value;
print(total); // Prints: 4.761904761904762
}
num process(num a, String operator, num b) {
switch (operator) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
}
throw ArgumentError(operator);
}
There are a few packages that can be used to accomplish this:
pub.dev/packages/function_tree
pub.dev/packages/math_expressions
pub.dev/packages/expressions
I used function_tree as follows:
double amount = 100.55;
String formula = '5/105*.5'; // From Postgres
final tax = amount * formula.interpret();
I haven't tried it, but using math_expressions it should look like this:
double amount = 100.55;
String formula = '5/105*.5'; // From Postgres
Parser p = Parser();
// Context is used to evaluate variables, can be empty in this case.
ContextModel cm = ContextModel();
Expression exp = p.parse(formula) * p.parse(amount.toString());
// or..
//Expression exp = p.parse(formula) * Number(amount);
double result = exp.evaluate(EvaluationType.REAL, cm);
// Result: 2.394047619047619
print('Result: ${result}');
Thanks to fkleon for the math_expressions help.
I am just starting with Spring Reactor and want to implement something that I would call 'standard pagination', don't know if there is technical term for this. Basically no matter what start and end date is passed to method, I want to return same amound of data, evenly distributed.
This will be used for some chart drawing in the future.
I figured out rough copy with algorithm that does exactly that, unfortunatelly before I can filter results I need to either count() or take last index() and block to get this number.
This block is surelly not the reactive way to do this, also it makes flux to call DB twice for data (or am I missing something?)
Is there any operator than can help me and get result from count() somehow down the stream for further usage, it would need to compute anyway before stream can be processed, but to get rid of calling DB two times?
I am using mongoDB reactive driver.
Flux<StandardEntity> results = Flux.from(
mongoCollectionManager.getCollection(channel)
.find( and(gte("lastUpdated", begin), lte("lastUpdated", end))))
.map(d -> new StandardEntity(d.getString("price"), d.getString("lastUpdated")));
Long lastIndex = results
.count()
.block();
final double standardPage = 10.0D;
final double step = lastIndex / standardPage;
final double[] counter = {0.0D};
return
results
.take(1)
.mergeWith(
results
.skip(1)
.filter(e -> {
if (lastIndex > standardPage)
if (counter[0] >= step) {
counter[0] = counter[0] - step + 1;
return true;
} else {
counter[0] = counter[0] + 1;
return false;
}
else
return true;
}));
I am using the WLST Ant task which allows a list of space delimited arguments to be passed in under the arguments attribute.
The issue is when I pass a file directory which contains a space. For instance "Program Files" which becomes two arguments of Program and Files.
Is there any suggestions to get around this?
My suggestion below would only work with one value.
For example append the "Program Files" argument to the end and loop from the known end argument to the actual end of sys.argv.
IE If we want "Program Files" to be the 4th system argument then inside the WLST script we append sys.argv[4],[5]...[end].
Short answer for WLST 11.1.1.9.0: You can't get around this.
I have the same problem and debugged a bit.
My findings:
The class WLSTTask in weblogic-11.1.1.9.jar calls via command line WLSTInterpreterInvoker which parses the args:
private void parseArgs(String[] arg) {
for (int i = 0; i < arg.length; i++) {
this.arguments = (this.arguments + " " + arg[i]);
}
[...]
For reasons I don't know these args are parsed again, before the python script is invoked:
private void executePyScript() {
[...]
if (this.arguments != null) {
String[] args = StringUtils.splitCompletely(this.arguments, " ");
[...]
public static String[] splitCompletely(String paramString1, String paramString2)
{
return splitCompletely(new StringTokenizer(paramString1, paramString2));
}
private static String[] splitCompletely(StringTokenizer paramStringTokenizer) {
int i = paramStringTokenizer.countTokens();
String[] arrayOfString = new String[i];
for (int j = 0; j < i; j++) arrayOfString[j] = paramStringTokenizer.nextToken();
return arrayOfString;
}
Unfortunately the StringTokenizer method does not distinguish quoted strings and so sys.argv in Python gets separate arguments, even if you quote the parameter
There are two possible alternatives:
Replace spaces in Ant with something else (eg %20) and 'decode' them in Python.
Write a property file in Ant and read from that in Pyhton.
The code for executePyScript() in 12.2.1 has changed a lot and it seems that the problem may be gone there (I haven't checked)
if ((this.arguments.indexOf("\"") == -1) && (this.arguments.indexOf("'") == -1))
args = StringUtils.splitCompletely(this.arguments, " ");
else {
args = splitQuotedString(this.arguments);
}
I need to write a job where i could fetch the index of an array element of EDT Dimension
e.g. In my EDT Dimension i have array elements A B C when i click over them for properties I see the index for A as 1, B as 2 and C as 3. Now with a job ui want to fetch the index value. Kindly Assist.
I'm not sure if I did understand the real problem. Some code sample could help.
The Dimensions Table has some useful methods like arrayIdx2Code.
Maybe the following code helps:
static void Job1(Args _args)
{
Counter idx;
Dimension dimension;
DimensionCode dimensionCode;
str name;
;
for (idx = 1; idx <= dimof(dimension); idx++)
{
dimensionCode = Dimensions::arrayIdx2Code(idx);
name = enum2str(dimensionCode);
// if (name == 'B') ...
info(strfmt("%1: %2", idx, name));
}
}
I found a way but still looking if there is any other solution.
static void Job10(Args _args)
{
Dicttype dicttype;
counter i;
str test;
;
test = "Client";
dicttype = new dicttype(132);//132 here is the id of edt dimension
for (i=1;i<=dicttype.arraySize();i++)
{
if ( dicttype.label(i) == test)
{
break;
}
}
print i;
pause;
}
Array elements A B C from your example are nothing else but simple labels - they cannot be used as identifiers. First of all, for user convenience the labels can be modified anytime, then even if they aren't, the labels are different in different languages, and so on and so forth.
Overall your approach (querying DictType) would be correct but I cannot think of any scenario that would actually require such a code.
If you clarified your business requirements someone could come up with a better solution.