Understanding cyclomatic complexity - checkstyle

I have some piece of code that basically looks like this:
public MyObject getData(boolean someFlag) {
String select1 = "SELECT * FROM myTable WHERE someInteger = ?";
SqlHostvariablen hostvars = new SqlHostvara();
hostvars.addInteger(myField.getSomeInteger);
String[][] selarray = SqlHelper.doSelectAsMatrix(select1, hostvars);
if (selarray.length == 0) {
throw new IllegalArgumentException("Nothing found");
}
MyObject foo = new MyObject();
int i = 0;
foo.setSomething1(selarray[0][i++]);
foo.setSomething2(selarray[0][i++]);
foo.setSomething3(selarray[0][i++]);
foo.setSomething4(selarray[0][i++]);
foo.setSomething5(selarray[0][i++]);
foo.setSomething6(selarray[0][i++]);
foo.setSomething7(selarray[0][i++]);
foo.setSomething8(transformSomething8(selarray[0][i++]));
foo.setSomething9(selarray[0][i++]);
foo.setSomething10(selarray[0][i++]);
String someValue1 = selarray[0][i++];
String someValue2 = selarray[0][i++];
foo.setSomething11(selarray[0][i++]);
doSomethingWithFoo(foo, someFlag, someValue1, someValue2);
doSomethingElseWithFoo(foo);
return foo;
}
The identifiers and SQL statement are anonymized but otherwise my method looks the same.
Now Checkstyle claims that the cyclomatic comlexity if this method is 12. I always thought I knew what CC was and from my knowledge I'd say this methods CC is 2. There is one if that creates a new path through the code and the control flow graph therefore has 2 paths/exit points. I don't see where else there should be a path through the code.
Am I missing something entirely or is Checkstyle just wrong?

Turned out this was a Checkstyle error. While not even cleaning the problem did the trick, after a system restart the warning was gone. An Eclipse restart might have been enough, no way to know for sure.

Related

Error in quick start guide

I'm new to encog, and I recently read the "Quick Start Guide"
However I found a things that I consider an error, can you confirm this?
In the final "chapter", "Using Encog for Time Series", the output is printed in the console using this code:
while (csv.next() && stopAfter > 0) {
StringBuilder result = new StringBuilder();
line[0] = csv.get(2);// ssn
line[1] = csv.get(3);// dev
helper.normalizeInputVector(line, slice, false);
// enough data to build a full window?
if (window.isReady()) {
window.copyWindow(input.getData(), 0);
String correct = csv.get(2); // trying to predict SSN.
MLData output = bestMethod.compute(input);
String predicted = helper
.denormalizeOutputVectorToString(output)[0];
result.append(Arrays.toString(line));
result.append(" -> predicted: ");
result.append(predicted);
result.append("(correct: ");
result.append(correct);
result.append(")");
The wrong I think it is wrong, is the "correct" variable: since it is predicting the SSN value from the CSV, it is right to read it using csv.get(2), but it should be invoked on time "t+1". In this code it is evaluated equals to SSN at time t
The output shows this too:
[9.4, 9.1] -> predicted: 16.576461298905144(correct: 9.4)
here it is clear that "correct" value is the same as input.
Am I missing anything?
thanks
A.

linq-to-sql fails if local list variable

I'm struggling to get what I thought would be a simple LINQ-to-SQL query to work. I can construct the query ok and can verify that the SQL it generates is correct but when executing get the dreaded "System.NotSupportedException: Queries with local collections are not supported" exception.
I've simplified my query but in short the query below works:
var query = from asset in context where new[] { 1, 2, 3 }.Contains(asset.code) select asset
this query also works:
var query = from asset in context where new List<int>() { 1, 2, 3 }.Contains(asset.code) select asset
But the query below will fail when an attempt is made to get the result set:
List<int> myList = new List<int>(){1, 2, 3};
var query = from asset in context where myList.Contains(asset.code) select asset
Anyone solved this sort of issue?
What you posted should work, leading me to believe you didn't actually post the broken code.
Make sure that the MyList variable is a List<int> and not an IList<int>... if the variable type is IList<int>, you'd get that exception.
This works fine for me in LINQPad:
List<int> myList = new List<int>(){1, 2, 3}; /* Fixed your compiler error here */
var query = from asset in assets where myList.Contains(asset.code) select asset;
As such, I assume you aren't actually using a List for myList, but rather a generic IEnumerable or something similar?
Please try pasting your "unsimplified" version, as your simplication corrects your error.

exception in Linq to sql

my query is :
var ReadAndUnreadMessages =
(from m in MDB.Messages
orderby m.Date descending
where m.ID_Receive == (Guid)USER.ProviderUserKey && m.Delete_Admin == false
select new AllMessages()
{
id = (LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).ID_Message,
parent = (Guid)(LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).ID_Message_Parent,
sender = (LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).ID_Sender,
receiver = (Guid)USER.ProviderUserKey,
subject = (LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).Subject.Subject1.ToString() == "Other" ?
(LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).Other_Subject
:
(LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).Subject.Subject1.ToString(),
body = (LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).Body.Length > 26 ?
(LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).Body.Substring(0, 25) + "..."
:
(LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).Body,
date = (LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).Date.ToShortDateString(),
read =(LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).IsRead,
finished = (LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).IsFinished,
count = MessageClass.LoadAll(m.ID_Message).Count
}).ToList();
and exception is :
The argument 'value' was the wrong type. Expected 'Message'. Actual 'System.Object'.
what does meaning it?
LoadMessageChildren :
public static ArrayList LoadMessageChildren(Guid Parent)
{
ArrayList arr = new ArrayList();
Guid id = Parent;
while (id != Guid.Empty)
{
arr.Add(LoadMessage(id));
try
{
id = (Guid)MDB.Messages.Single(a => a.ID_Message_Parent == id).ID_Message;
}
catch
{
id = Guid.Empty;
}
}
return arr;
}
LoadMessage :
public static Message LoadMessage(Guid id)
{
var mess = from m in MDB.Messages
where m.ID_Message == id
select m;
return mess.Single();
}
The code is unreadable, and as a bad case of code repetition (and multiple executions of LoadMessageChildren).
For starters, consider the following:
from m in MDB.Messages
orderby m.Date descending
where m.ID_Receive == (Guid)USER.ProviderUserKey && m.Delete_Admin == false
let children = LoadMessageChildren(m.ID_Message)
let lastChildMessage = children.Last()
select new AllMessages()
{
id = lastChildMessage.ID_Message,
...
}
This may solve your problem, as it is might be caused by using the [] indexer.
Aside from that, it is not clear the posted code is causing the exception.
The only thing I see you using LoadChildMessages() for in the end is to get the child message count... Unless I am wrong I would think you could write it as a join. You doing a lot of queries with in queries that don't seem necessary and are probably causing multiple hits to the database. My question to that would be why isn't there a relationship in your dmbl/sql database so that LinqToSql knows to create a property as a List<Message> ChildMessages
But here is my take:
var query = from message in MDB.Messges
join childmessage in MDB.Messages.Where(child => child.ID_Message_Parent == message.ID_Message) into childMessages
from childMessage in childMessages.DefaultIfEmpty() // This creates a
// left outer join so you get parent messages that don't have any children
where message.ID_Receive == (Guid)USER.ProviderUserKey && message.Delete_Admin == false
select new AllMessages()
{
id = message.ID_Message,
parent = message.ID_Message_Parent,
sender = message.ID_Sender,
receiver = (Guid)USER.ProviderUserKey,
subject = message.Subject.Subject1.ToString() == "Other" ?
message.Other_Subject
:
message.Subject.Subject1.ToString(),
body = message.Body.Length > 26 ?
message.Body.Substring(0, 25) + "..."
:
message.Body,
date = message.Date.ToShortDateString(),
read =message.IsRead,
finished = message.IsFinished,
count = childMessage.Count() // This might have to be this
//count = childMessage == null ? 0 : childMessage.Count()
};
var ReadAndUnreadMessages = query.ToList();
But it's hard to say because I can't run the code... Please respond and let me know if this works.
Note: May I suggest using a class that links to your DataContext.Log property that writes the generated TSQL code to the debugger window. Here is an article on writing your own. It has really help me know when I am making unnecessary calls to the database.
The error is most likely caused by the use of the ArrayList.
The problem is that LINQ was designed to work with generic collections that implement the System.Collections.Generic.IEnumerable<T> interface. The ArrayList is a nongeneric collection that internally stores everything as an Object. So when you retrieve something from the ArrayList you need to cast it to a Message.
Looking at your error message it looks like somewhere a Message object is expected, but the instance in your ArrayList (an Object) is not casted to a Message object when that reference occurs. Also, the ArrayList does not implement the IEnumerable<T> interface which might get you into trouble in certain situations also.
How to fix it?
I suggest changing the implementation of your LoadMessageChildren to use a generic list (List<Message>):
public static List<Message> LoadMessageChildren(Guid Parent)
{
List<Message> arr = new List<Message>();
Guid id = Parent;
while (id != Guid.Empty)
{
arr.Add(LoadMessage(id));
try
{
id = (Guid)MDB.Messages.Single(a => a.ID_Message_Parent == id).ID_Message;
}
catch
{
id = Guid.Empty;
}
}
return arr;
}
You will have to make also change the code that interacts with the generic list in terms of retrieving/referencing items. But that is just syntax. Since equivalent methods for dealist with lists and items exist.
There are also advantages in terms of performance and compile-time validation for switching from ArrayList to List<T>. The ArrayList is basically an inheritance from version 1.0 of the .Net Framework when there was no support for generics and it just get kept in the framework probably for compatibility reasons.
There are greater benefits for using generics.
UPDATED ANSWER:
The "Method 'System.Collections.Generic.List'1[Message] LoadMessageChildren(System.Guid)' has no supported translation to SQL" exception that you are getting is caused by the fact that your LoadMessageChildren method is not mapping to a stored procedure or a user defined function in your database.
You cannot have any regular C# method call inside your LINQ to SQL queries. The LINQ to SQL object model interprets a method found inside your query as either a stored procedure or a user defined function. So the engine is basically looking for a method called LoadMessageChildren that maps to a stored procedure or a user defined function in your database. Because there are no mappings, it tells you that no supported translation to SQL was found. The LINQ to SQL object model link shows you how to use method attributes to map a method that executes a stored procedure.
You have a few choices now:
create stored procedures of your regular C# method calls
rewrite your LINQ query to use joins to select child messages

why this Linq to sql function return nulls?

I am new to linq to sql
I wrote this function:
public ICollection<ICustomer> GetAll()
{
DataClasses1DataContext context = new DataClasses1DataContext();
var customers = from customer in context.Customers select customer;
return customers.ToList().Cast<ICustomer>().ToList();
}
But it always return list of null values.
The database contain 3 records "filled with data" but this function return 3 nulls.
how to fix that?
It may not be able to cast the results properly, have you made your partial Customer object implement ICustomer? If not, that is the reason.
Also you don't have to bring it to a list twice, or even once for that matter since you aren't returning a list, it might be more appropriate to change your signature to List or IEnumerable depending on your usage.
You can test whether or not the cast is succeeding by doing a simple test.
DataClasses1DataContext context = new DataClasses1DataContext();
var customers = from customer in context.Customers select customer;
int numberOfCustomers = customers.Count();
var myCustomers = customers.Cast<ICustomer>(); //you could also do .OfType<ICustomer>();
int numberOfICustomers = myCustomers.Count();
If numberOfCustomers is 3 and numberOfICustomers is 0 then you know that was the issue.
Your problem is almost certainly at the .Cast() method (confirm this by stepping through your code & ensuring that customers is populated correctly).
Does the Customer object implement the ICustomer interface? It sounds like an obvious thing to check but that would be a likely problem.

Linq: Simple Boolean function returns linq Exception

I have a Linq query that looks something like this:
var query = from x in table where SomeFunctionReturnsBool() select;
private bool SomeFunctionReturnsBool()
{
return true;
}
This returns and exception that says "SomeFunctionReturnsBool has no supported translation to SQL". I get that this is because it wants to treat "SomeFunctionReturnsBool" as an expression to evaluate as SQL, but it can't.
Although this Linq query isn't complicated, the real ones are. How can I accomplish what I'm trying to do here, which is to break out pieces of the query to hopefully make it more readable?
Jeff
UPDATE
Good answers. I am trying now to work with expressions instead, but this code gets me "cannot resolve method Where(lambda expression)":
var query = from x in table where SomeFunctionReturnsBool() select x;
private Expression<Func<EligibilityTempTable, bool>> SomeFunctionReturnsBool
{
return (x) => true;
}
Another way is to use Expression<Func<YourType, bool>> predicate...
var query = from x in table where SomeFunctionReturnsBool() select;
Edit: I don't usually do it the way I've shown above... I was just getting that from the code above. Here is the way I usually implement it. Because then you can tack on additional Enumerable methods or comment them out during debugging.
var results = table.Where(SomeFunctionReturnsBool())
.OrderBy(yt => yt.YourProperty)
//.Skip(pageCount * pageSize) //Just showing how you can easily comment out parts...
//.Take(pageSize)
.ToList(); //Finally executes the query...
private Expression<Func<YourType, boo>> SomeFunctionReturnsBool()
{
return (YourType yt) => yt.YourProperty.StartsWith("a")
&& yt.YourOtherProperty == true;
}
I prefer to use the PredicateBuilder which allows you to build an expression to be used in your Where...
You can do this in LINQ-to-SQL by creating a UDF mapped to the data-context; this involves writing TSQL, and use ctx.SomeFunctionblah(...).
The alternative is to work with expression trees - for example, it could be:
Expression<Func<Customer, bool>> SomeFunc() {
return c => true; // or whatever
}
and use .Where(SomeFunc()) - is that close enough? You can't use the query syntax in this case, but it gets the job done...
Added dodgy Where method to show how you might use it in query syntax. I don't suggest this is fantastic, but you might find it handy.
using System;
using System.Linq;
using System.Linq.Expressions;
static class Program
{
static void Main()
{
using (var ctx = new NorthwindDataContext())
{
ctx.Log = Console.Out;
// fluent API
var qry = ctx.Customers.Where(SomeFunc("a"));
Console.WriteLine(qry.Count());
// custom Where - purely for illustration
qry = from c in ctx.Customers
where SomeFunc("a")
select c;
Console.WriteLine(qry.Count());
}
}
static IQueryable<T> Where<T>(this IQueryable<T> query,
Func<T, Expression<Func<T, bool>>> predicate)
{
if(predicate==null) throw new ArgumentNullException("predicate");
return query.Where(predicate(default(T)));
}
static Expression<Func<Customer, bool>> SomeFunc(string arg)
{
return c => c.CompanyName.Contains(arg);
}
}
Basically, "out of the box", you can't have LINQ-to-SQL execute queries that have custom functions in them. In fact only some native methods that can be translated to SQL can be used.
The easiest way around this can unfortunately affect performance depending on how much data you're bringing back from the DB.
Basically, you can only use custom functions in WHERE statments if the data has already been loaded into memory, i.e, SQL have already executed.
The quickest fix for your example would look like this:
var query = from x in table.ToList() where SomeFunctionReturnsBool() select;
Notice the ToList(). It executes the SQL and puts the data into memory. You can now do whatever you want in the WHERE statement/method.
I would just break them out like so:
Expression<Func<Table, bool>> someTreeThatReturnsBool = x => true;
var query = from x in table where someTreeThatReturnsBool select x;
You could create functions that pass around expression trees.
Don't use query syntax for this.
var query = table.Where( x => SomeFunction(x) );