simple math issue - jasper-reports

I'm trying to modify an existing JasperReports template for an invoice. I would like to do some simple math in one field, i.e. calcultate the tax from an existing gross value. The gross value is represented by a parameter $P{prevAdvanceLine1Sum} and in the next field I would like to simply divide this value by a number (in my case 1.23).
Can you give me the expression I should use and what expression class to set?

You can either use simple arithmetic operators (like " / " in this case. See example here: EL Basic Arithmetic), or use the pre-defined methods provided by iReports. Which means, right-click upon the TextField and select Edit Expression. Then select the divide() method.
So the two methods would be:
1. $P{prevAdvanceLine1Sum / 1.23}
2. $P{prevAdvanceLine1Sum}.divide( 1.23 )

Related

How to use MDriven OclPs to find all objects matching a list of strings?

In an application I receive a list of strings. Then I want to use OclPs to find all objects where a specific attribute equals any of the strings in the list. E.g. if we have Person objects and receive a list of last names, find all persons whose last name appears in the list.
Although this can surely be done in MDriven's in-memory OCL engine, I can't seem to achieve this in the more limited OclPs (which translates the OCL to SQL and evaluates it as such in the database).
Attempt 1: First assign the list of names to vNames (collection of strings), then:
Person.allInstances->select(p|vNames->exists(n|n = p.LastName))
This gives error "Loop variables can only have class type, not System.String".
Attempt 2: First assign a "|" separated string of the sought names, including leading and trailing "|", to vNames, then:
Person.allInstances->select(p|vNames.SqlLike('%|' + p.LastName + '|%'))
This gives error saying strings cant be added in Firebird. But Firebird does support string concatenation using the || operator.
Trying with .Contains(...) instead of .SqlLike(...) says it's not supported in OclPs. Besides, it would find persons with a last name that is CONTAINED in any of the sought names, i.e. an incorrect search.
I'm out of ideas...
In this case when you have a long list of strings and you want a list of objects I think you best option is to use SQL with sqlpassthroughobjects:
https://wiki.mdriven.net/index.php/OCLOperators_sqlpassthroughobjects
Person.sqlpassthroughobjects('select personid from person where lastname in ('+vNames->collect(n|'\''+n+'\'')->asCommaList+')')
oclPS only implements a quite small subset of OCL because its converting the OCL to sql.
For example, collections of "non-objects" can't be used.
Person.allInstances->select(p|vNames.SqlLike('%|' + p.LastName + '|%'))
Instead, look at sqlpassthroughobjects here
https://wiki.mdriven.net/index.php/OCLOperators_sqlpassthroughobjects
You could also insert the names as objects of a class into the database and then use oclPS.
I suggest that you use a genuine OCL tool. You seem to be demonstrating that MDriven OclPs is not OCL.

Nette how to subtract timestamp from current date

how can i subtract number of days (timestamp|date'z') from current day (date('z')) in latte? I've tryes to use var but that does not like the formating (z).
Latte filters, unlike function calls, are not something that can be applied to any part of an expression – they are only optional feature of the variable printing macro.
{expression_to_be_printed|filter1|filter2|filter3}
date filter mostly just calls format method so you can use it directly:
{(new DateTime())->format('z') - $timestamp->format('z')}
This, however, will not work if the $timestamp lies in a different year.
To fix this, you can use DateTime’s diff method. DateInterval, returned by the method, can then be formatted using format method which provides difference in the number of days through %a formatting string.
{$timestamp->diff(new DateTime())->format('%a')}
Fortunately, the date filter also allows formatting intervals.
{$timestamp->diff(new DateTime())|date:'%a'}
Admittedly, this looks kind of ugly. A better way would be to define a custom filter so you could just use {$post->timestamp|daysAgo}. See Latte docs about creating your own filters.

Simplify boolean expression i.t.o variable occurrence

How to simplify a given boolean expression with many variables (>10) so that the number of occurrences of each variable is minimized?
In my scenario, the value of a variable has to be considered ephemeral, that is, has to recomputed for each access (while still being static of course). I therefor need to minimize the number of times a variable has to be evaluated before trying to solve the function.
Consider the function
f(A,B,C,D,E,F) = (ABC)+(ABCD)+(ABEF)
Recursively using the distributive and absorption law one comes up with
f'(A,B,C,E,F) = AB(C+(EF))
I'm now wondering if there is an algorithm or method to solve this task in minimal runtime.
Using only Quine-McCluskey in the example above gives
f'(A,B,C,E,F) = (ABEF) + (ABC)
which is not optimal for my case. Is it save to assume that simplifying with QM first and then use algebra like above to reduce further is optimal?
I usually use Wolfram Alpha for this sort of thing.
Try Logic Friday 1
It features multi-level design of boolean circuits.
For your example, input and output look as follows:
You can use an online boolean expression calculator like https://www.dcode.fr/boolean-expressions-calculator
You can refer to Any good boolean expression simplifiers out there? it will definitely help.

How can I make the value of an expression equal to a second return value of another expression

Is there an idiomatic way in Matlab to bind the value of an expression to the nth return value of another expression?
For example, say I want an array of indices corresponding to the maximum value of a number of vectors stored in a cell array. I can do that by
function I = max_index(varargin)
[~,I]=max(varargin{:});
cellfun(#max_index, my_data);
But this requires one to define a function (max_index) specific for each case one wants to select a particular return value in an expression. I can of course define a generic function that does what I want:
function y = nth_return(n,fun,varargin)
[vals{1:n}] = fun(varargin{:});
y = vals{n};
And call it like:
cellfun(#(x) nth_return(2,#max,x), my_data)
Adding such functions, however, makes code snippets less portable and harder to understand. Is there an idiomatic to achieve the same result without having to rely on the custom nth_return function?
This is as far as I know not possible in another way as with the solutions you mention. So just use the syntax:
[~,I]=max(var);
Or indeed create an extra function. But I would also suggest against this. Just write the extra line of code, in case you want to use the output in another function. I found two earlier questions on stackoverflow, which adress the same topic, and seem to confirm that this is not possible.
Skipping outputs with anonymous function in MATLAB
How to elegantly ignore some return values of a MATLAB function?
The reason why the ~ operator was added to MATLAB some versions ago was to prevent you from saving variables you do not need. If there would be a syntax like the one you are searching for, this would not have been necessary.

how to deal with complex branching in iReport or Jasper

I need to fill a field in a report based on the end result of a complex branching statement. How do I do this in iReport? The report needs to show a different string depending on what is in different fields in the database. Do I make a really complex SQL statement? Do I use variables?
So, for instance,
If field x=1
IF y=1
IF z=1
Field should read A
If x=1
IF y=1
IF z=2
Field should read B
You could do something similar to the following:
( $F{staff_type} == null ? new String("") :
( $F{staff_type}.equalsIgnoreCase("Permanent") ? new String("1") :
( $F{staff_type}.equalsIgnoreCase("Non-permanent") ? new String("2") : new String("")
)))
Basically, you need to use nested condition expressions.
in the textfieldexpression write an expression like this
(($F{PAYMENTMODE}.equals("CS")) ? "Cash":($F{PAYMENTMODE}.equals("CQ"))? "Cheque":"Bank")e
I think the easiest way to do this would be to have the field(s) filled by a parameter passed from the backing bean. The jdbc connection is created in the bean and passed to the report, it should be relatively easy to access the field or fields you need and run the data through a method which determines the branching outcome. Assign the outcome to the parameter and pass it to the report in the jasperParameter variable of JasperFillManager.fillReport(file, parameters, jdbcConnection).
Usually, I handle all the programming logic before passing the data to the Jasper Report Engine, but in some cases, post-processing or post-checking is required. If it is that scenario and If I had MANY cases (strings) to check, I would code a 'Jasper Report Scriptlet' and handle that logic there (so that the code/report is readable and maintainable and also for code reuse). If it is just 2 or 3 strings to check, I would use the 'Ternary' operator.
If you want to use report scriptlet, create a scriptlet class (or use an existing one), code a method to handle this logic (Ex: 'checkString' method) and put $P{REPORT_SCRIPTLET}.checkString(someString) in the TextField's expression.