Using a string comparison in a boolean that was defined as a command line argument - boolean

I am writing a program to determine the cost of gasoline, given the price-per-gallon and the amount of gallons purchased, but also given the payment method (cash or credit). To read the payment method, I have defined a String named paymentMethod as the third argument input in the command line, as shown below:
public class gas{
public static void main(String[] args){
double pricePerGallon=Double.parseDouble(args[0]);
double gallonsPurchased=Double.parseDouble(args[1]);
String paymentMethod=args[2];
String cash="cash";
String credit="credit";
if (pricePerGallon>0 && gallonsPurchased>0){
**if (paymentMethod==cash)**
{
System.out.println(pricePerGallon*gallonsPurchased);
}
else if (paymentMethod==credit)
{
System.out.println(1.1*pricePerGallon*gallonsPurchased);
}
}
else{
System.out.println("Error");
}
}
}
I'm seeing if the third argument (which is a string) is the string "cash", in which case the cost of the gas is calculated and printed. If it is credit, there's an additional 10% charge.
Problems are arising with the boolean " (paymentMethod==cash) ". My program is compiling and I can run it but when I hit enter, nothing is returned. Not even the computation of the price.

You need to use the equals method. The == operator does not work on Strings in Java as you would want it to.
Change:
if (paymentMethod==cash)
to
if (paymentMethod.equals(cash))
And similarly for the credit conditional also.

Related

DROOLS - double amount

I am creating a condition like the following:
$event : EventObject(type=='Sale', $points:points, $playerid:playerid) from
entry-point eventstream
The consequence of this I need to pass the variables to the following:
boolean givePointsToPlayer(String playerId,
String pointType,
double amount,
String notificationMessage)
The most basic example below is me giving 3 points to this player
updateAPIv1.givePointsToPlayer($playerid, 'Points', 3, 'Points Awarded');
update(engine.getPlayerById($playerid));
However, I want to pass the $points:points to 'double amount'.
Simple question I know but how best would I do this? Something like?
$points=double amount;
updateAPIv1.givePointsToPlayer($playerid, 'Points', amount, 'Points Awarded');
update(engine.getPlayerById($playerid));;
Appreciate feedback. Thanks.
***Update I tried also
$event : EventObject(type=='Sale', $points:points, $playerid:playerid)
from entry-point eventstream
updateAPIv1.givePointsToPlayer($playerid, 'Points', $points, 'Points Awarded');
update(engine.getPlayerById($playerid));
but I get the following errors for this
"Unable to create Field Extractor for 'points'
Field/method 'points' not found for class 'com.sap.gamification.model.EventObject"
"Rule Compilation error $points cannot be resolved "
Any thoughts on this?
You should very quickly catch up on Java syntax, since this is an invalid statement.
$points=double amount;
However, you do not need to store the value of a bound variable ($points) to another variable in the consequence. You can write this call:
updateAPIv1.givePointsToPlayer($playerid, 'Points', $points, 'Points Awarded');
Think of variables bound to fact fields as "final" variables: you can access the value but not change it.
Edit This assumes that you have:
public class EventObject {
private double points;
public double getPoints(){ return points; }
// ... rest of class
}

get double value from bigdecimal without exponential java

is there a way to get double from BigDecimal without exponential?
Eg: I have an new BigDecimal("123456797676.897")
if i print new BigDecimal("123456797676.897").toString() it prints properly as 123456797676.897.
Now suppose if I try to print new BigDecimal("123456797676.897").doubleValue(), it prints with exponential like 1.23456797676897E11.
Is there any way I can get doublevalue with out exponential.
Thanks :)
The following program demonstrates that these are all exactly the same double:
new BigDecimal("123456797676.897").doubleValue()
123456797676.897
1.23456797676897E11
12.3456797676897E10
The Double toString method has to pick one representation for each value. For numbers greater than 107 it uses exponential notation with a single digit before the decimal point. That is a generally reasonable choice, but it is not always the right choice. If you want it displayed without the exponent use DecimalFormat. If you are just using the number, it makes no difference whether Double's toString would have displayed it with an exponent or not, and you don't need to do anything about it.
import java.math.BigDecimal;
public class Test {
public static void main(String[] args) {
double doubleValue = new BigDecimal("123456797676.897").doubleValue();
double simpleLiteral = 123456797676.897;
double exponent11Literal = 1.23456797676897E11;
double exponent10Literal = 12.3456797676897E10;
System.out.println(doubleValue == simpleLiteral);
System.out.println(doubleValue == exponent11Literal);
System.out.println(doubleValue == exponent10Literal);
}
}
output:
true
true
true

Get Class from string -- Call function by string name

OK, what I'm trying to do is fairy complicated, but I'll try to explain.
Let's say we want (at compile-time) all derivedMembers of class someClass. Then we'd simply do :
const string[] methods = [__traits(derivedMembers,someClass)];
Now, how could we get someClass from "someClass"? (yep, its string representation).
Let me explain a bit more what I'm trying to do :
I want to create an "intermediate" function which takes a function name as an argument (along with a params array) and calls the appropriate function from a list of available static methods in a specific (predefined) set of classes. Like execute("someFunc",["one","two","three"]);.
Here's the full (test) code :
class Math {
static string noArgs(string[] s) { writeln(s); return ""; }
static string withOneArg(string[] s) { writeln(s); return ""; }
static string withTwoArgs(string[] s) { writeln(s); return ""; }
}
string cases()
{
string ret = "";
const string[] methods = [__traits(derivedMembers,Math)];
foreach (string s; methods)
{
ret ~= "case \"" ~ s ~ "\": return Math."~s~"(params);";
}
return ret;
}
string execute(string what, string[] params)
{
switch (what)
{
mixin(cases());
default: break;
}
return "";
}
The trouble with the above code is that it only looks for methods in Math. How could I change it, in an elegant D-friendly way, so that it'll go through an array of classes like [Math,String,SomethingElse] -- it doesn't have to be variable (we need it at compile-time anyway)?
UPDATE:
Tried something along the lines of :
const string[] methods = [__traits(derivedMembers,mixin("Math")];
but it complains that Cannot interpret Math at compile time.
UPDATE 2:
Also, tried using Object.factory("Math") but it's still not working. (Perhaps I'm just creating an instance of the Math class?)
Let me rewrite this to show you some cool tricks:
import std.stdio;
class Math {
static string noArgs(string[] s) { writeln(s); return ""; }
static string withOneArg(string[] s) { writeln(s); return ""; }
static string withTwoArgs(string[] s) { writeln(s); return ""; }
}
class String {
static string oneArg(string[] s) { return null; }
}
string execute(string what, string[] params) {
import std.string;
auto parts = what.split(".");
auto className = parts[0];
auto methodName = parts[1];
import std.typetuple;
switch(className) {
default: assert(0, "unknown class");
foreach(possibleClass; TypeTuple!(Math, String)) {
case possibleClass.stringof:
switch(methodName) {
default: assert(0, "unknown method");
foreach(memberName; __traits(derivedMembers, possibleClass)) {
case memberName:
return __traits(getMember, possibleClass, memberName)(params);
break;
}
}
break;
}
}
assert(0);
}
void main() {
execute("Math.withOneArg", ["cool"]);
execute("String.oneArg", ["cool"]);
}
Notice that there are no mixin expressions used at all. Instead of getting an instance of the class from a string, I just made a TypeTuple of all the classes I wanted to use. This is preferable to mixin because then it is less likely to find name classes when used in different scopes; if possibleClasses were a compile-time parameter to execute from a different module, the list of classes would still work, whereas the list of strings would see undefined identifier errors because the library module doesn't import your user module.
Another mixin I removed was the one to generate the cases. This looks insane, but is allowed in D: if you have a compile-time foreach (that is, a foreach over a built-in tuple of some sort, e.g. TypeTuple, template argument lists, the results of __traits...) you can actually put case statements inside them!
So, all you have to do is write a regular switch statement on the run time variable you want to compare against, put the foreach inside it looping over the compile-time stuff you're searching for, case that_loop_var: and boom, you're in business.
Similarly, I used __traits(getMember) rather than a mixin string to call the method. This solution will help avoid name clashes and IMO is cleaner code. It can also potentially handle overloads, if wanted (with __traits(getOverloads) instead of __traits(getMember), you can loop over each one then and match the parameter types).
Finally, nesting switches inside other case statements is allowed. If you need to break out of an outer loop or switch and don't want ambiguity, you can label loops and switches and use break label_name_here; to specify which one you want to break from. Ditto for continue with nested loops.
BTW you could also automatically generate the wrapper functions that convert string[] to other types of arguments if you dove into the std.traits stuff. I wish my book was out already, I wrote about this at some length in there and don't feel like writing it all right now but if you look at std.traits.ParameterTypeTuple and ReturnType in the same module that will get you started if you wanna try it.

AspectJ: Change target in an advice

I have pointcut the String .hashCode in an around adivce. I would like to change the target (String) to uppercase then proceed with the call to original hashCode. I'm not sure how to do that, the following code doesnt work properly.
#Pointcut("call(int hashCode(..)) && target(sourceString) && within(com.sample.package..*)")
public void hashCodePointcut(final String sourceString) {}
#Around("hashCodePointcut(sourceString)")
public Object around(final ProceedingJoinPoint joinPoint, String sourceString)
throws Throwable {
System.out.println("<<<<<<<<<<<<<<<<<Invoking hashCode on "+joinPoint.getSourceLocation().getFileName());
System.out.println("<<<<<<<<<<<<<<<<<Target String: "+ sourceString);
sourceString = sourceString.toUpperCase();
return joinPoint.proceed();
}
Let me preface this answer by saying that I advise strongly against using this. IMO, once you start mucking about with hash-methods after the fact and making the result less unique (by ignoring case in Strings, etc.) you are wading hip-deep in future problems and firmly on the dark side of coding. With that said strongly enough, here's how I'd do it:
#Pointcut("call(int java.lang.String.hashCode(..)) && target(sourceString) && within(com.sample.packages..*) && !within(your.package.AspectClass)")
public void hashCodePointcut(final String sourceString) {}
#Around("hashCodePointcut(sourceString)")
public Object around(final ProceedingJoinPoint joinPoint, String sourceString)
throws Throwable {
System.out.println("<<<<<<<<<<<<<<<<<Invoking hashCode on"+joinPoint.getSourceLocation().getFileName());
System.out.println("<<<<<<<<<<<<<<<<<Target String: "+ sourceString);
sourceString = sourceString.toUpperCase();
return sourceString.hashCode();
}
I have not tried this yet, but it should reroute all calls to the String.hashCode() method to a call of the same method on the .toUpperCase() of that String. It has to be done this way because you can not change the target of the joinPoint (which is why your advice probably does nothing as it is).
The addition of "!within(your.package.AspectClass)" to the pointcut prevents the same advice to be applied in an infinite loop on your calls within the aspect.
Let me know if this helps, or if there's still something going wrong (aside from the fact that you are mucking about with hashCode() ;) ).

C# lambda expressions and lazy evaluation

One advantage of lambda expressions is that you have to evaluate a function only when you need its result.
In the following (simple) example, the text function is only evaluated when a writer is present:
public static void PrintLine(Func<string> text, TextWriter writer)
{
if (writer != null)
{
writer.WriteLine(text());
}
}
Unfortunately, this makes using the code a little bit ugly. You cannot call it with a constant or variable like
PrintLine("Some text", Console.Out);
and have to call it this way:
PrintLine(() => "Some text", Console.Out);
The compiler is not able to "infer" a parameterless function from the passed constant. Are there any plans to improve this in future versions of C# or am I missing something?
UPDATE:
I just found a dirty hack myself:
public class F<T>
{
private readonly T value;
private readonly Func<T> func;
public F(T value) { this.value = value; }
public F(Func<T> func) {this.func = func; }
public static implicit operator F<T>(T value)
{
return new F<T>(value);
}
public static implicit operator F<T>(Func<T> func)
{
return new F<T>(func);
}
public T Eval()
{
return this.func != null ? this.func() : this.value;
}
}
Now i can just define the function as:
public static void PrintLine(F<string> text, TextWriter writer)
{
if (writer != null)
{
writer.WriteLine(text.Eval());
}
}
and call it both with a function or a value.
I doubt that C# will get this feature, but D has it. What you've outlined is a suitable way to implement lazy argument evaluation in C#, and probably compiles very similarly to lazy in D, and in more pure functional languages.
All things considered, the four extra characters, plus optional white space, are not an exceptionally large price to pay for clear overload resolution and expressiveness in what is becoming a multi-paradigm strong-typed language.
The compiler is very good at inferring types, it is not good at inferring intent. One of the tricky things about all the new syntactic sugar in C# 3 is that they can lead to confusion as to what exactly the compiler does with them.
Consider your example:
() => "SomeText"
The compiler sees this and understands that you intend to create an anonymous function that takes no parameters and returns a type of System.String. This is all inferred from the lambda expression you gave it. In reality your lambda gets compiled to this:
delegate {
return "SomeText";
};
and it is a delegate to this anonymous function that you are sending to PrintLine for execution.
It has always been important in the past but now with LINQ, lambdas, iterator blocks, automatically implemented properties, among other things it is of the utmost importance to use a tool like .NET Reflector to take a look at your code after it is compiled to see what really makes those features work.
Unfortunately, the ugly syntax is all you have in C#.
The "dirty hack" from the update does not work, because it does not delay the evaluation of string parameters: they get evaluated before being passed to operator F<T>(T value).
Compare PrintLine(() => string.Join(", ", names), myWriter) to PrintLine(string.Join(", ", names), myWriter) In the first case, the strings are joined only if they are printed; in the second case, the strings are joined no matter what: only the printing is conditional. In other words, the evaluation is not lazy at all.
Well those two statements are completely different. One is defining a function, while the other is a statement. Confusing the syntax would be much trickier.
() => "SomeText" //this is a function
"SomeText" //this is a string
You could use an overload:-
public static void PrintLine(string text, TextWriter writer)
{
PrintLine(() => text, writer);
}
You could write an extension method on String to glue it in. You should be able to write "Some text".PrintLine(Console.Out); and have it do the work for you.
Oddly enough, I did some playing with lazy evaluation of lambda expressions a few weeks back and blogged about it here.
To be honest I don't fully understand your problem, but your solutions seems a tad complicated to me.
I think a problem I solved using lambda call is similar, maybe you could use it as inspiration: I want to see if a key exists in a dictionary, if not, I would need to execute a (costly) load operation.
public static class DictionaryHelper
{
public static TValue GetValueOrLambdaDefault<TKey, TValue> (this IDictionary<TKey, TValue> dictionary, TKey key, Func<TValue> func)
{
if (dictionary.ContainsKey(key))
return dictionary[key];
else
return func.Invoke();
}
}
[TestClass]
public class DictionaryHelperTest
{
[TestMethod]
public void GetValueOrLambdaDefaultTest()
{
var dict = new Dictionary<int, string>();
try
{
var res1 = dict.GetValueOrLambdaDefault(1, () => LoadObject());
Assert.Fail("Exception should be thrown");
}
catch { /*Exception should be thrown*/ }
dict.Add(1, "");
try
{
var res1 = dict.GetValueOrLambdaDefault(1, () => LoadObject());
}
catch { Assert.Fail("Exception should not be thrown"); }
}
public static string LoadObject()
{
throw new Exception();
}
}