Writing code Javascript and other languages - coding-style

What is the general consenses, in this case i will be using JavaScript as an example:
Which one is more clear and correct A or B.. ? Please explain why, it might help others with their own coding style
A) Assign value to variable then check variable, then return value
...
mm = fecha.getMonth().length;
if (mm<=1)
{
return '0' + mm;
}
...
B) Check value directly then return value
...
if (fecha.getMonth().length<=1)
{
return '0'+ fecha.getMonth().length;
}
...

If you just want to condition the value and not using it later
if (fecha.getMonth().length<=1){
...
}
No need to create another variable which name could be used later and would lead to an error
let month = fecha.getMonth();
if( month.length<=1 ){
...
}
...
let month = document.querySelector('input#month').value; // Error 'month' has already been declared
...
If you have to check the value and furthermore use it
mm = fecha.getMonth().length;
if (mm<=1)
return mm;
}
Keeps the code clean when there are cases like this
aType = document.querySelector('A').children[0].classList[0].split('-')[1]
if(aType != 'relative'){
return document.querySelectorAll(aType)[1];
}
Which otherwise it would look like this
if(document.querySelector('A').children[0].classList[0].split('-')[1] != 'relative'){
return document.querySelectorAll(document.querySelector('A').children[0].classList[0].split('-')[1])[1];
}

Related

Talend: Save variable for later use

I´m trying to save a value in spreadsheet's header for later use as a new column value.
This is the reduced version with value (XYZ) in header:
The value in header must be used for new column CODE:
This is my design:
tFilterRow_1 is used to reject rows without values in A, B, C columns.
There is a conditional in tJavaRow_1 to set a global variable:
if(String.valueOf(row1.col_a).equals("CODE:")){
globalMap.putIfAbsent("code", row1.col_b);
}
The Var expression in tMap_1 to get the global variable is:
(String)globalMap.get("code")
The Var "code" is mapped to column "code" but I'm getting this output:
a1|b1|c1|
a2|b2|c2|
a3|b3|c3|
What is missed or there is a better approach to accomplish this escenario ?
Thanks in advance.
Short answer:
I tJavaRow use the input_row or the actual rowN in this case row4.
Longer answer, how I'd do it.
I'd do is let the excel flow in AS-IS. By using some Java tricks we can simply skip the first few rows then let the rest of the flow go through.
So the filter + tjavarow combo can be replaced with a tJavaFlex.
tJavaFlex I'd do:
begin:
boolean contentFound = false;
main
if(input_row.col1 != null && input_row.col1.equalsIgnoreCase("Code:") ) {
globalMap.put("code",input_row.col2);
}
if(input_row.col1 != null && input_row.col1.equalsIgnoreCase("Column A:") ) {
contentFound = true;
} else {
if(false == contentFound) continue;
}
This way you'll simply skip the first few records (i.e header) and only care about the actual data.

Can I override a Lua table's return value for itself?

Is it possible for a table, when referenced without a key, to return a particular value rather than a reference to itself?
Let's say I have the following table:
local person = {
name = "Kapulani",
level = 100,
age = 30,
}
In Lua, I can quite easily refer to "person.name", "person.level", or "person.age" and get the values as expected. However, I have certain cases where I may want to just reference "person" and, instead of getting "table: " I'd like to return the value of "person.name" instead.
In other words, I'd like person.x (or person[x]) to return the appropriate entry from the table, but person without a key to return the value of person.name (or person["name"]). Is there a mechanism for this that I haven't been able to find?
I have had no success with metatables, since __index will only apply to cases where the key does not exist. If I put "person" into a separate table, I can come up with:
local true_person = {
... -- as above
}
local env_mt = {
__index = function(t, k)
if k == 'person' then
return true_person
end
end
}
local env = setmetatable( {}, env_mt )
This lets me use __index to do some special handling, except there's no discernable way for me to tell, from __index(), whether I'm getting a request for env.person (where I'd want to return true_person.name) or env.person[key] (where I'd want to return true_person as a table, so that 'key' can be accessed appropriately).
Any thoughts? I can approach this differently, but hoping I can approach this along these lines.
You can do it when the table is being used as a string by setting the __tostring metatable entry:
$ cat st.lua
local person = {
name = "Kapulani",
level = 100,
age = 30,
}
print(person)
print(person.name)
print(person.age)
setmetatable(person, {__tostring = function(t) return t.name end})
print(person)
$ lua st.lua
lua st.lua
table: 0x1e8478e0
Kapulani
30
Kapulani
I am not sure that what you are asking for is a good idea because it flies in the face of compositionality. Usually one would expect the following two programs to do the same thing but you want them to behave differently
print(person.name)
local p = person
print( p.name )
Its also not very clear how assignment would work. person.age = 10 should change the age but person = otherPerson should change the reference to the perrson, not the age.
If you don't care about compositionality and are onyl reading data, then a more direct way to solve the problem is to have a query function that receives the fields encoded in a string
query("person.age") -- 17
query("person.name") -- "hugomg"
query("person") -- 17; query gets to default to whatever it wants.
To keep the syntax more lightweight you can omit the optional parenthesis
q"person.age"
q"person"
Or you can extend the __index metamethod on the global table, _G
setmetattable(_G, { __index = function(self, key) return query(key) end })
print ( person_age ) -- You will need to use "_" instead of "." for the
-- query to be a valid identifier.

how to check for a value in the last 10 entries using linq to entities

I have method where I need to retrieve using EF the last ten entries in the database and check to see if there is a match between the value and the current term. Here is what I have thus far
public static int ValidatePassword(string username, string password, int securityUserId)
{
int validResult = 0;
/*Need to pass to client a value based upon success or failure of validation
* 0 - success
* 1 - password has already been used in the last 10 entries
* 2 - password does not meet CJIS requirements
*/
IEnumerable<string> oldpassword = null;
// Create a Regular Expression to determine whether or not special characters are present.
Regex regularExpression = new Regex("[^a-z0-9]");
//if id exists pull last ten passwords
if (securityUserId > 0)
{
long id = Convert.ToInt64(securityUserId);
using (var context = new SecurityEntities(string.Empty))
{
try
{
oldpassword = (from p in context.SecurityAudits
where p.SecurityUserId == id &&
p.OldPassword == password
orderby p.ActionDate descending
select p.OldPassword.Take(10).ToString()).ToList();
}
catch (Exception ex)
{
string err = string.Format("ValidateCJISPassword() was unable to return an object msg:{0}", ex.Message);
throw new Exception(err, ex.InnerException);
}
finally
{
context.Dispose();
}
}
}
else if (oldpassword == null)
{
//no matching record found now check other requirements
if ((password.Length >= DEFAULT_CJIS_PASSWORD_MIN_LENGTH) && regularExpression.IsMatch(password) && (password != username))
{
//success
validResult = 0;
}
else
{
//password does not meet standard CJIS requirements
validResult = 2;
}
}
else
{
//matching record was found
validResult = 1;
}
return validResult;
}
}
Where I am currently hung up is the query throws an exception on the ToString() method
LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression.
I'm still learning EF and how linq works so I'm not sure what the best approach here is. Should I try to set the result to something other than IEnumerable like an array or List or is there another approach I should consider?
Thanks in advance,
Cheers,
Change this
oldpassword = (from p in context.SecurityAudits
where p.SecurityUserId == id &&
p.OldPassword == password
orderby p.ActionDate descending
select p.OldPassword.Take(10).ToString()).ToList();
To this
oldpassword = (from p in context.SecurityAudits
where p.SecurityUserId == id &&
p.OldPassword == password
orderby p.ActionDate descending
select p.OldPassword).Take(10).ToList();
The problem was that your Take(10) clause was not part of the whole result but inside the actual linq statement.. it goes on the outside of it to take the top 10 of the entire resultset.. then you do the ToList() which turns the whole thing into an array
The next problem is that you just created an array and assigned it to oldpassword
I don't see anything here that does anything with the array...
You need to do something like:
declare your array of strings
assign the array to the return of the linq query
evaluate the return for > 0 results
if > 0 then the password has been used in the last 10
if = 0 then new password should be ok, correct?
Now that I have an understanding of what I needed in the query I was able to also update the linq statement as follows:
var lastTenPassword = (from p in context.SecurityAudits.Take(10)
orderby p.ActionDate descending
where p.SecurityUserId == id
select p.OldPassword).ToList();
string oldpassword = lastTenPassword.Where(a => a == password).FirstOrDefault();
Testing is further down the line but now by moving the .Take() method inside the query I am explicitly grabbing the top ten where as my first attempt would have retrieved all the records and then grabbed the top ten.
For testing you can also see where I broke out the initial where() to first grab all records by id and then perform a filter on that set by looking for a matching password within that set.
Thanks again for your help

compare datetime and timespan value

I want to compare datetime value and timespan value for the reason of non-negative value checking ..
my code is here:
TimeSpan lateaftertime = new TimeSpan();
lateaftertime = Convert.ToDateTime(intime) - lateafter;
string latetime = lateaftertime.Hours + ":" + lateaftertime.Minutes;
if ((lateafter < lateaftertime))
{
Session["late"] = "00:00";
}
else
{
Session["late"] = latetime;
}
suppose late after returns negative value means the session["late"] have the value 00:00 otherwise the session maintain the difference value
please help me. i was trouble this..
Your question is pretty unclear, but it sounds like you really want:
if (lateaftertime < TimeSpan.Zero)
{
Session["late"] = "00:00";
}
else
{
Session["late] = latetime;
}
or more concisely:
Session["late"] = lateaftertime < TimeSpan.Zero ? "00:00" : latetime;
It's possible you want > rather than < here - it's hard to tell what you're trying to achieve. Sample data would make it clearer. You should also rename your variables to be more conventional, e.g. lateAfterTime instead of lateafterime

LINQ to SQL bug (or very strange feature) when using IQueryable, foreach, and multiple Where

I ran into a scenario where LINQ to SQL acts very strangely. I would like to know if I'm doing something wrong. But I think there is a real possibility that it's a bug.
The code pasted below isn't my real code. It is a simplified version I created for this post, using the Northwind database.
A little background: I have a method that takes an IQueryable of Product and a "filter object" (which I will describe in a minute). It should run some "Where" extension methods on the IQueryable, based on the "filter object", and then return the IQueryable.
The so-called "filter object" is a System.Collections.Generic.List of an anonymous type of this structure: { column = fieldEnum, id = int }
The fieldEnum is an enum of the different columns of the Products table that I would possibly like to use for the filtering.
Instead of explaining further how my code works, it's easier if you just take a look at it. It's simple to follow.
enum filterType { supplier = 1, category }
public IQueryable<Product> getIQueryableProducts()
{
NorthwindDataClassesDataContext db = new NorthwindDataClassesDataContext();
IQueryable<Product> query = db.Products.AsQueryable();
//this section is just for the example. It creates a Generic List of an Anonymous Type
//with two objects. In real life I get the same kind of collection, but it isn't hard coded like here
var filter1 = new { column = filterType.supplier, id = 7 };
var filter2 = new { column = filterType.category, id = 3 };
var filterList = (new[] { filter1 }).ToList();
filterList.Add(filter2);
foreach(var oFilter in filterList)
{
switch (oFilter.column)
{
case filterType.supplier:
query = query.Where(p => p.SupplierID == oFilter.id);
break;
case filterType.category:
query = query.Where(p => p.CategoryID == oFilter.id);
break;
default:
break;
}
}
return query;
}
So here is an example. Let's say the List contains two items of this anonymous type, { column = fieldEnum.Supplier, id = 7 } and { column = fieldEnum.Category, id = 3}.
After running the code above, the underlying SQL query of the IQueryable object should contain:
WHERE SupplierID = 7 AND CategoryID = 3
But in reality, after the code runs the SQL that gets executed is
WHERE SupplierID = 3 AND CategoryID = 3
I tried defining query as a property and setting a breakpoint on the setter, thinking I could catch what's changing it when it shouldn't be. But everything was supposedly fine. So instead I just checked the underlying SQL after every command. I realized that the first Where runs fine, and query stays fine (meaning SupplierID = 7) until right after the foreach loop runs the second time. Right after oFilter becomes the second anonymous type item, and not the first, the 'query' SQL changes to Supplier = 3. So what must be happening here under-the-hood is that instead of just remembering that Supplier should equal 7, LINQ to SQL remembers that Supplier should equal oFilter.id. But oFilter is a name of a single item of a foreach loop, and it means something different after it iterates.
I have only glanced at your question, but I am 90% sure that you should read the first section of On lambdas, capture, and mutability (which includes links to 5 similar SO questions) and all will become clear.
The basic gist of it is that the variable oFilter in your example has been captured in the closure by reference and not by value. That means that once the loop finishes iterating, the variable's reference is to the last one, so the value as evaluated at lambda execution time is the final one as well.
The cure is to insert a new variable inside the foreach loop whose scope is only that iteration rather than the whole loop:
foreach(var oFilter in filterList)
{
var filter = oFilter; // add this
switch (oFilter.column) // this doesn't have to change, but can for consistency
{
case filterType.supplier:
query = query.Where(p => p.SupplierID == filter.id); // use `filter` here
break;
Now each closure is over a different filter variable that is declared anew inside of each loop, and your code will run as expected.
Working as designed. The issue you are confronting is the clash between lexical closure and mutable variables.
What you probably want to do is
foreach(var oFilter in filterList)
{
var o = oFilter;
switch (o.column)
{
case filterType.supplier:
query = query.Where(p => p.SupplierID == o.id);
break;
case filterType.category:
query = query.Where(p => p.CategoryID == o.id);
break;
default:
break;
}
}
When compiled to IL, the variable oFilter is declared once and used multiply. What you need is a variable declared separately for each use of that variable within a closure, which is what o is now there for.
While you're at it, get rid of that bastardized Hungarian notation :P.
I think this is the clearest explanation I've ever seen: http://blogs.msdn.com/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx:
Basically, the problem arises because we specify that the foreach loop is a syntactic sugar for
{
IEnumerator<int> e = ((IEnumerable<int>)values).GetEnumerator();
try
{
int m; // OUTSIDE THE ACTUAL LOOP
while(e.MoveNext())
{
m = (int)(int)e.Current;
funcs.Add(()=>m);
}
}
finally
{
if (e != null) ((IDisposable)e).Dispose();
}
}
If we specified that the expansion was
try
{
while(e.MoveNext())
{
int m; // INSIDE
m = (int)(int)e.Current;
funcs.Add(()=>m);
}
then the code would behave as expected.
The problem is that you're not appending to the query, you're replacing it each time through the foreach statement.
You want something like the PredicateBuilder - http://www.albahari.com/nutshell/predicatebuilder.aspx

Resources