[rules-users] Problems count and sumarizing data in facts

Yamil Bracho yamilbracho at hotmail.com
Fri Mar 12 09:46:30 EST 2010

```I considered BigDecimal but I do not know if sum works with BigDecimal and afert that I think I have to  use the long version of accumulate.I think convert all to Integer or Long could be a better idea...
Again, thanks Thomas

From: TSwindells at nds.com
To: rules-users at lists.jboss.org
Date: Fri, 12 Mar 2010 09:06:37 +0000
Subject: Re: [rules-users] Problems count and sumarizing data in facts

Rather than having a toDouble method have a toPennies method which converts the string into an integer instead.  This would make sure that there are no rounding
issues and be a bit cleaner.  BigDecimal would be another option but probably slightly more complicated.
Even better would be fix it all the way upstream but I’m guess that that probably isn’t an option.

Thomas

From: rules-users-bounces at lists.jboss.org [mailto:rules-users-bounces at lists.jboss.org]
On Behalf Of Yamil Bracho

Sent: 11 March 2010 19:00

To: Drools UserList

Subject: Re: [rules-users] Problems count and sumarizing data in facts

Thomas, I am aware about this issue and it is my second item in the list to fix.

The only solution I got is convert all to String and this way works OK

rule "Sumatoria de lineas detalle vs Header"

salience 10

when

Number( \$total : doubleValue) from accumulate(

Map(this["_TYPE_"] == "D",

\$monto : this["MONTO"]),

sum(toDouble(\$monto)))

\$map : Map(this["_TYPE_"] == "H",

\$totEnc : this["MT_TOTAL"]) &&

not (eval(isNumEquals(\$totEnc, \$total)))

then

"Error en el Detalle: El total de las lineas de detalle (" +  formatDouble(\$total) +

") no empareja con lo del encabezado (" + formatDoubleObj(\$totEnc) + ")"));

end

function boolean isNumEquals(Object oNum1, double num2) {

return formatDoubleObj(oNum1).equals(formatDouble(num2));

}

function String formatDouble(double d) {

return (new DecimalFormat("#,###.00")).format(d);

}

function String formatDoubleObj(Object obj) {

return formatDouble(toDouble(obj));

}

The "isNumEquals" compare the numbers by comparing their String representations.

yes, I think this is not so elegant and I would like a better solutions...

Regards

From: TSwindells at nds.com

To: rules-users at lists.jboss.org

Date: Thu, 11 Mar 2010 16:17:05 +0000

Subject: Re: [rules-users] Problems count and sumarizing data in facts

Well done for getting this working shame how complex it has to be. It would be nice/very very useful if drools provided a simple way of converting between
numeric strings and numbers as I’ve also faced this problem before and it seems to require really big ugly hacks to work round the issue.

With respect to your solution I’d still reiterate the point I made in the post below about the fact that you may not get the result you are expecting,

As 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1 != 1.0 you may get spurious error messages when you shouldn’t.

Thomas

From: rules-users-bounces at lists.jboss.org [mailto:rules-users-bounces at lists.jboss.org]
On Behalf Of Yamil Bracho

Sent: 11 March 2010 15:52

To: Drools UserList

Subject: Re: [rules-users] Problems count and sumarizing data in facts

Thanks Enda.

Yes, I read carefully the docs and understand that eval expected a boolena expression.

I succesfully change the rule to :

rule "Sumatoria de lineas detalle vs Header"

salience 10

when

Number( \$total : doubleValue) from accumulate(

Map(this["_TYPE_"] == "D",

\$monto : this["MONTO"]),

sum(toDouble(\$monto)))

\$map : Map(this["_TYPE_"] == "H",

\$totEnc : this["MT_TOTAL"]) &&

eval(toDouble(\$totEnc) != \$total)

then

System.out.println("Encabezado:" + toDouble(\$totEnc) + ", Detalle=" + \$total);

"Error en el Detalle: El número del lineas de detalle (" +  \$total +

") no empareja con lo del encabezado (" + \$map.get("NU_REGISTROS") + ")"));

end

Where "toDouble" is a function :

function double toDouble(Object oMonto) {

String strMonto = oMonto.toString();

int len = strMonto.length();

int pos = len - 2;

strMonto = StringUtils.left(strMonto, pos) + "." + StringUtils.right(strMonto,2);

//return Double.valueOf(strMonto)  ;

double d = Double.parseDouble(strMonto);

return d;

}

Thanks to Enda and Thomas for help me to solve this...

Date: Thu, 11 Mar 2010 15:02:33 +0000

From: ejdiggins at gmail.com

To: rules-users at lists.jboss.org

Subject: Re: [rules-users] Problems count and sumarizing data in facts

Hi Yamil,

'eval()' expects a primitive boolean value as a result of the expression. You may need to look into creating a custom accumulate function that can accept a string and do the conversion in java. Have a look at section 6.5.2.10.1 Accumulate Function in the Drools
documentation:

Alternatively, you could change the type of your map to something like Map<String, Double>

Hope it helps,

Enda

2010/3/11 Yamil Bracho <yamilbracho at hotmail.com>

I rewrote as :

rule "Sumatoria de lineas detalle vs Header"

salience 10

when

Number( \$total : doubleValue) from accumulate(

Map(this["_TYPE_"] == "D",

\$monto : this["MONTO"]),

sum(eval(toDouble(\$monto))))

\$map : Map(this["_TYPE_"] == "H",

this["MT_TOTAL"] != \$total)

then

System.out.println("TOTAL=" + \$total);

"Error en el Detalle: El número del lineas de detalle (" +  \$total +

") no empareja con lo del encabezado (" + \$map.get("NU_REGISTROS") + ")"));

end

Where "toDouble" is :

function Double toDouble(Object oMonto) {

String strMonto = oMonto.toString();

int len = strMonto.length();

int pos = len - 3;

strMonto = StringUtils.left(strMonto, pos) + "." + StringUtils.right(strMonto,2);

return Double.valueOf(strMonto)  ;

}

And I got

Rule Compilation error : [Rule name='Sumatoria de lineas detalle vs Header']

rule/Rule_Sumatoria_de_lineas_detalle_vs_Header_0.java (9:1350) : The method eval(Double) is undefined for the type Rule_Sumatoria_de_lineas_detalle_vs_Header_0

Thanks again, Thomas..!

From:
TSwindells at nds.com

To: rules-users at lists.jboss.org

Date: Thu, 11 Mar 2010 09:25:31 +0000

Subject: Re: [rules-users] Problems count and sumarizing data in facts

Have you tried assigning the string to \$monto and then performing the evel within the sum?

From:
rules-users-bounces at lists.jboss.org [mailto:rules-users-bounces at lists.jboss.org]
On Behalf Of Yamil Bracho

Sent: 10 March 2010 19:38

To: Drools UserList

Subject: Re: [rules-users] Problems count and sumarizing data in facts

Thanks Thomas.

I rewrote the rule as:

rule "Sumatoria de lineas detalle vs Header"

salience 10

when

Number( \$total : doubleValue) from accumulate(

Map(this["_TYPE_"] == "D",

\$monto : eval(Double.parseDouble(this.get("MONTO")))),

sum(\$monto))

\$map : Map(this["_TYPE_"] == "H",

this["MT_TOTAL"] != \$total)

then

System.out.println("TOTAL=" + \$total);

"Error en el Detalle: El número del lineas de detalle (" +  \$total +

") no empareja con lo del encabezado (" + \$map.get("NU_REGISTROS") + ")"));

end

but I am getting errors in the parseDouble:

[828,29]: [ERR 101] Line 828:29 no viable alternative at input 'Double' in rule "Sumatoria de lineas detalle vs Header" in pattern Map[828,67]: [ERR 102] Line 828:67 mismatched
input ')' expecting 'then' in rule "Sumatoria de lineas detalle vs Header"

Any hint...

From:
TSwindells at nds.com

To: rules-users at lists.jboss.org

Date: Wed, 10 Mar 2010 15:13:49 +0000

Subject: Re: [rules-users] Problems count and sumarizing data in facts

To convert from string to double you have to full back to java:

Something along the lines  of

\$monto : eval(Double.parseDouble(this.get(“MONTO”)))

However even with doing this your rules are unlikely to work consistently as you expect.  Using equality tests on doubles is fundamentally unsafe as doubles aren’t represented
exactly and may not exactly match the value you think you have.  Force instance 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1 != 1.0 (dependent on floating point chipset etc).  If you are dealing with currency then it is far simpler and safer to just operate with
integers and divide by 100 when you want to display the value.  The other alternative is to use BigDecimal which will store an exact representation but will probably require more work with getting your accumulate function correct.  Your last option is to use
Math.abs(left-right) < 0.1 to see if they are approximately equal.  More details can be found here
http://firstclassthoughts.co.uk/java/traps/java_double_traps.html

Thomas

From:
rules-users-bounces at lists.jboss.org [mailto:rules-users-bounces at lists.jboss.org]
On Behalf Of Yamil Bracho

Sent: 10 March 2010 14:27

To: Drools UserList

Subject: Re: [rules-users] Problems count and sumarizing data in facts

I solved the counting of detail lines this way:

salience 10

when

Number(\$count : intValue) from accumulate(

\$mp : Map(this["_TYPE_"] == "D"), count(\$mp))

\$map : Map(this["_TYPE_"] == "H",

this["NU_REGISTROS"] != \$count)

then

System.out.println("NumRecs=" + \$count);

"El número del lineas de detalle (" + \$count +

") no empareja con lo del encabezado (" + \$map.get("NU_REGISTROS") + ")"));

end

However, I still got problem with summarize the amounts. I wrote

rule "Sumatoria de lineas detalle vs Header"

salience 10

when

Number( \$total : doubleValue) from accumulate(

Map(this["_TYPE_"] == "D",

\$monto : ((Number) this["MONTO"]),

sum(\$monto)))

\$map : Map(this["_TYPE_"] == "H",

this["MT_TOTAL"] != \$total)

then

System.out.println("TOTAL=" + \$total);

"Error en el Detalle: El número del lineas de detalle (" +  \$total +

") no empareja con lo del encabezado (" + \$map.get("NU_REGISTROS") + ")"));

end

And i am getting  mismatched input" so my question is how to convert a string to double in this line "\$monto : ((Number) this["MONTO"])," ?

TIA

Yamil

From:
yamilbracho at hotmail.com

To: rules-users at lists.jboss.org

Date: Tue, 9 Mar 2010 17:41:43 +0000

Subject: [rules-users] Problems count and sumarizing data in facts

Hi, I have two kind of facts in a map.

There is a field called _TYPE_ (H)eader, D)etail)

In the Header line I have two String fields, one for the number of details lines ("NU_REGISTROS") and another for the sum of the detail line ("MT_TOTAL")

In the detail lines I only have a String field called "MONTO"

I would like to build two rules. One to check the count of detail lines versus the field in the header line so I wrote :

salience 10

when

\$numRecs : Number()

from accumulate(Map(this["_TYPE_"] == "D", \$d : this["_NUMLINE_"]), count(\$d))

\$map : Map(this["_TYPE_"] == "H",

this["NU_REGISTROS"] != \$numRecs)

then

System.out.println("NumRecs=" + \$numRecs);

"Error en el Detalle: El número del lineas de detalle (" +  \$total +

") no empareja con lo del encabezado (" + \$map.get("NU_REGISTROS") + ")"));

end

However I always got "NumRecs=1" when i print out the value of \$numRecs but I am absolute sure there is two details lines...

Second when i try to sumarize the total field in the details line i got (MONTO in the detail line is a string):

rule "Sumatoria de lineas detalle vs Header"

salience 10

when

\$total : Number()

from accumulate(Map(this["_TYPE_"] == "D",

\$monto : this["MONTO"]),

sum(eval(Double.valueOf((String) \$monto ))))

\$map : Map(this["_TYPE_"] == "H",

this["MT_TOTAL"] != \$total)

then

System.out.println("TOTAL=" + \$total);

"Error en el Detalle: El número del lineas de detalle (" +  \$total +

") no empareja con lo del encabezado (" + \$map.get("NU_REGISTROS") + ")"));

end

but I got

Rule Compilation error : [Rule name='Sumatoria de lineas detalle vs Header']

rule/Rule_Sumatoria_de_lineas_detalle_vs_Header_0.java (9:1313) : The method eval(Double) is undefined for the type Rule_Sumatoria_de_lineas_detalle_vs_Header_0

Any help in those tow problems

TIA

Yamil

Actualízate gratis al nuevo Internet Explorer 8 y
navega más seguro

Compartir tus mejores FOTOS es fácil en Messenger
¡DESCUBRE cómo!

**************************************************************************************

This message is confidential and intended only for the addressee. If you have received this message in error, please immediately notify the
postmaster at nds.com and delete it from your system as well as any copies. The content of e-mails as well as traffic data may be monitored by NDS for employment and security purposes. To protect the environment please do
not print this e-mail unless necessary.

NDS Limited. Registered Office: One London Road, Staines, Middlesex, TW18 4EX, United Kingdom. A company registered in England and Wales. Registered no. 3080780. VAT no. GB 603 8808 40-00

**************************************************************************************

This message is confidential and intended only for the addressee. If you have received this message in error, please immediately notify the
postmaster at nds.com and delete it from your system as well as any copies. The content of e-mails as well as traffic data may be monitored by NDS for employment and security purposes.

To protect the environment please do not print this e-mail unless necessary.

An NDS Group Limited company. www.nds.com

¿Sabes que la Videollamada de Messenger es GRATIS
¡Descúbrela!

**************************************************************************************

This message is confidential and intended only for the addressee. If you have received this message in error, please immediately notify the
postmaster at nds.com and delete it from your system as well as any copies. The content of e-mails as well as traffic data may be monitored by NDS for employment and security purposes. To protect the environment please do
not print this e-mail unless necessary.

NDS Limited. Registered Office: One London Road, Staines, Middlesex, TW18 4EX, United Kingdom. A company registered in England and Wales. Registered no. 3080780. VAT no. GB 603 8808 40-00

**************************************************************************************

This message is confidential and intended only for the addressee. If you have received this message in error, please immediately notify the
postmaster at nds.com and delete it from your system as well as any copies. The content of e-mails as well as traffic data may be monitored by NDS for employment and security purposes.

To protect the environment please do not print this e-mail unless necessary.

An NDS Group Limited company. www.nds.com

¿Quieres saber qué móvil eres?
¡Descúbrelo aquí!

_______________________________________________

rules-users mailing list

rules-users at lists.jboss.org

https://lists.jboss.org/mailman/listinfo/rules-users

--

Enda J Diggins

Actualízate gratis al nuevo Internet Explorer 8 y
navega más seguro

**************************************************************************************

This message is confidential and intended only for the addressee. If you have received this message in error, please immediately notify the postmaster at nds.com and delete it from your system as well as any copies. The content of e-mails as well as traffic data
may be monitored by NDS for employment and security purposes. To protect the environment please do not print this e-mail unless necessary.

NDS Limited. Registered Office: One London Road, Staines, Middlesex, TW18 4EX, United Kingdom. A company registered in England and Wales. Registered no. 3080780. VAT no. GB 603 8808 40-00

**************************************************************************************

This message is confidential and intended only for the addressee. If you have received this message in error, please immediately notify the postmaster at nds.com and
delete it from your system as well as any copies. The content of e-mails as well as traffic data may be monitored by NDS for employment and security purposes.

To protect the environment please do not print this e-mail unless necessary.

An NDS Group Limited company. www.nds.com

¿Quieres saber qué móvil eres?
¡Descúbrelo aquí!

**************************************************************************************

This message is confidential and intended only for the addressee. If you have received this message in error, please immediately notify the postmaster at nds.com and delete it from your system as well as any copies. The content of e-mails as well as traffic data
may be monitored by NDS for employment and security purposes. To protect the environment please do not print this e-mail unless necessary.

NDS Limited. Registered Office: One London Road, Staines, Middlesex, TW18 4EX, United Kingdom. A company registered in England and Wales. Registered no. 3080780. VAT no. GB 603 8808 40-00

**************************************************************************************

This message is confidential and intended only for the addressee. If you have received this message in error, please immediately notify the postmaster at nds.com and delete it from your system as well as any copies. The
content of e-mails as well as traffic data may be monitored by NDS for employment and security purposes.

To protect the environment please do not print this e-mail unless necessary.

An NDS Group Limited company. www.nds.com

_________________________________________________________________
Recibe en tu móvil un SMS con tu Hotmail recibido. ¡Date de alta ya!
http://serviciosmoviles.es.msn.com/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20100312/cff8a031/attachment.html
```