Autohotkey If Statement makes only one result - if-statement

I wanted to run a program on working day only,
so I wrote a AutoHotKey script to check "today is sunday or holiday"
But my script doesn't work and I didn't get what the problem is.
Here is the code.
Result = "WorkingDay"
if(A_Wday = 1) {
Result = "Sunday"
}
HolidayList = 0101|0211|0212|0213|0301|0409|0501|0505|0519|0606|0815|0920|0921|0922|1003|1009|1225
StringSplit,HoliDay,HoliDayList,|
StringLeft,Today,A_Now,8
StringRight,Today,Today,4
Loop %Holiday0%
{
CheckDay := HoliDay%A_index%
; msgbox, %Today% = %CheckDay%
if ( %Today% == %CheckDay% ) {
Result = "Holiday"
break
}
}
msgbox, %Today% = %Result%
The problem is that the "Result" variable return only "Holiday"
Please help me out......... Thanks in advance.

Basically you're just using a whole bunch of legacy code, and trying to mix in some modern non-legacy stuff, and they really don't mix well unless you know very well how to do it.
Biggest issue is this right here:
if ( %Today% == %CheckDay% )
By trying to use the legacy way of referring to variables in a non legacy if ()(docs), bad things happen. You're trying to use dynamic variables, and you really don't want that, so what actually happens is that you check if nothing == nothing, and that's always going to return true.
How you're actually supposed to refer to variables in a modern expression statement, is just
if (Today = CheckDay)
(when comparing, = and == are for case insensitive and case sensitive comparing, you probably meant to do =)
And now it should work.
Here's the whole code in modern AHK:
Result := "WorkingDay"
if (A_Wday = 1)
Result := "Sunday"
HolidayList := "0101|0211|0212|0213|0301|0409|0501|0505|0519|0606|0815|0920|0921|0922|1003|1009|1225"
Holidays := StrSplit(HolidayList, "|")
Today := SubStr(A_Now, 5, 4)
for each, Holiday in Holidays
{
if (Today = Holiday)
{
Result := "Holiday"
break
}
}
MsgBox, % Today " = " Result
I don't have time to explain it more right now, but to learn about legacy vs modern AHK, I recommend this documentation page and this previous answer of mine:
https://www.autohotkey.com/docs/Language.htm
When to use % or %variable% in AutoHotKey?

Related

Google app script IF condition not matching 0, empty and null

I have issues with Google app script IF condition.
Problem i am facing its not returning value TRUE rather going to next/ Else statements.
Code i am having:
const numberOfRowsToUpdate = deliveryDate.length;
// For each item making the for loop to work
for (i=0 ; i < numberOfRowsToUpdate;i++) {
debugger;
var dp = depositAmount[i];
if(dp!==""|| dp!==0 || dp !==null || dp!==isblank())
{ .... <statements>
}
}
I want to check whether particular cell of the array is empty / zero / returning null value.
thanks in advance for the help.
SUGGESTION
I have used a similar script I'm using for a spreadsheet in which I need to search through every row for some data, but obviously adpating it to your case, and since I don't have your full code (and still can't comment asking for more info due to my recent joining in SO), I had to simplify it, in hope it will work for you.
What I did was use your incrementing i index from the for loop and use it to scan every row, while adjusting it to fit your array index, because we can't have i = 0 as a row index, and it would skip the first value on the array if left as i = 1).
SCRIPT
function test(){
const n = 6;
var depositAmount = [7,2,0,2,0,8];
// For each item making the for loop to work
var ss = SpreadsheetApp.getActive();
Logger.log(ss.getName());
for (var i=1 ; i <= n ;i++) {
debugger;
ss.getRange("A"+i).setValue(1);
var dp = depositAmount[i-1];
Logger.log(dp)
if(dp != "" || dp != 0 /*|| dp != null || dp != isblank()*/)
{
ss.getRange("B"+i).setValue(dp);
}
else
{
ss.getRange("C"+i).setValue("VOID")
Logger.log(i-1+"th index of array is "+ss.getRange("C"+i).getValue());
}
}
};
RESULTS
After running it with the four original conditions you used, i didn't get the expected result, as you must have, leading to this:
.
While studying your original code, I stumbled upon this question about the differences between == and ===, as well as != and !==.
So before I used this in our favor, I tried the old trial and error method, using only one condition at a time, and then stacking them up. Not only I managed to find out the !== operator didn't work properly for this case, but also the comparison with null and the isblank() function (at least in my case, because i haven't defined it, and I'm not sure it is a built-in function) also don't work with either operator.
Therefore, using the != operator helps you better than the strict !==.
The result of the final script is that:
.
NOTES
I also tried using a null value within the array ([7,2,0,2,,8]), but it would always break away from the loop, never scanning the whole array, and I don't know how to circle that.
Here is the Execution Log for this script:
EDIT
While fooling around, I found this question and the answer by Etienne de Villers might be even faster to apply, or at least more useful for your purposes.

Prestashop WebService "limit" parameter not working as expected

I'm trying to use the limit parameter in PrestaShop's WebService.
My problem is it's only half working, the number of entries to display is working fine, but the "starting point" is not.
For example:
http://example.com/api/combinations?display=[id,reference]&limit=[0,500]&sort=id_ASC&ws_key=WEBSERVICEKEY
AND
http://example.com/api/combinations?display=[id,reference]&limit=[500,500]&sort=id_ASC&ws_key=WEBSERVICEKEY
Returns exactly the same products (first 500).
I am using PS 1.6.1.17
I've updated the classes/webservice folder with the latest (from 1.6.1.18).
The code (classes/webservice/WebserviceRequest.php) - no override:
$sql_limit = '';
if (isset($this->urlFragments['limit'])) {
$limitArgs = explode(',', $this->urlFragments['limit']);
if (count($limitArgs) > 2) {
$this->setError(400, 'The "limit" value has to be formed as this example: "5,25" or "10"', 39);
return false;
} else {
$sql_limit .= ' LIMIT '.(int)($limitArgs[0]).(isset($limitArgs[1]) ? ', '.(int)($limitArgs[1]) : '')."\n";// LIMIT X|X, Y
}
}
The code looks fine, maybe it's SQL related? I'd like to print the generated query to test it but I couldn't fin a way...
I've found the problem.
The int cast wasn't working here.
$this->urlFragments['limit'] value is [500,500].
So after explode $limitArgs[0] is equal to [500 but the code (int)($limitArgs[0]) was always giving me 0 instead of 500 as result.
I replaced it with an ugly str_replace as follow:
$sql_limit .= ' LIMIT '.str_replace("[", "", $limitArgs[0]).(isset($limitArgs[1]) ? ','.(int)($limitArgs[1]) : '')."\n";// LIMIT X|X, Y
Not the best, but could be usefull if anyone faces this situation.
edit: I posted on the forge, the correct syntax for limit is limit=X,Y not limit=[X,Y].

Modify Mongodb source code to disable auto-generating "_id" field for doc

I want to modify and compile the latest source code of mongodb(as of now, mongodb version v3.5.10-34-g27d21e6 from github) to make the _id field not automatically generated if not provided when inserting a document. The current official release of mongodb requires the existence of this field (I have tested this fact on mongodb-win32-x86_64-v3.4-latest from https://www.mongodb.org) .
I found a related question Mongodb inserting doc without _id field. But I think my question does not duplicate with this one because mine is asking for source code modification while this one is about parameter setting (whose answers are also no longer workable for current version of mongodb).
I know that the official mongodb group have their reasons and considerations to require such an _id field and since they have decided to introduce such a requirement, it's not likely that they will remove it in the near future. And I also know that disabling _id will affect some functionality of mongodb such as replication mentioned above. But I still want to know how to disable it since I will just use it as a personal database running only one instance on a single machine. I am sure I won't need other functionalities. Storage is what I considered most so I don't want this field take additional disk space. And for the same reason I need the wiredTiger engine with the compression abilities so I need to do this to a relatively new version of mongodb.
As of now, I have successfully compiled and linked the original source code v3.5.10-34-g27d21e6 using scons with VS2015 installed. So I hope someone can tell me which code segment/segments of which source code file/files I should modify to disable auto-generating _id field; and which files also need to be "patched" that would check the existence of _id and refuse to work properly if not found even if they don't really need it.
The below two files are what I have found that seems related:
1) mongo/src/mongo/db/ops/insert.cpp line:153-177
I tried to modify this file as follows but after which _id is still auto created
from:
if (firstElementIsId) {
b.append(doc.firstElement());
i.next();
} else {
BSONElement e = doc["_id"];
if (e.type()) {
b.append(e);
} else {
b.appendOID("_id", NULL, true);
}
}
while (i.more()) {
BSONElement e = i.next();
if (hadId && e.fieldNameStringData() == "_id") {
// no-op
} else if (e.type() == bsonTimestamp && e.timestampValue() == 0) {
auto nextTime = LogicalClock::get(service)->reserveTicks(1);
b.append(e.fieldName(), nextTime.asTimestamp());
} else {
b.append(e);
}
}
to:
if (firstElementIsId) {
//b.append(doc.firstElement());
i.next();
} else {
BSONElement e = doc["_id"];
if (e.type()) {
//b.append(e);
} else {
//b.appendOID("_id", NULL, true);
}
}
while (i.more()) {
BSONElement e = i.next();
if (hadId && e.fieldNameStringData() == "_id") {
// no-op
} else if (e.fieldNameStringData() == "_id") {
// no-op
} else if (e.type() == bsonTimestamp && e.timestampValue() == 0) {
auto nextTime = LogicalClock::get(service)->reserveTicks(1);
b.append(e.fieldName(), nextTime.asTimestamp());
} else {
b.append(e);
}
}
2) mongo/src/mongo/bson/bsonobj.cpp line:281-315
I didn't modify this file because I didn't see which line of code may add the _id field, just feel it may related to the question from what it mentioned in its comment.
/* note: addFields always adds _id even if not specified
returns n added not counting _id unless requested.
*/
int BSONObj::addFields(BSONObj& from, set<string>& fields) {
verify(isEmpty() && !isOwned()); /* partial implementation for now... */
BSONObjBuilder b;
int N = fields.size();
int n = 0;
BSONObjIterator i(from);
bool gotId = false;
while (i.moreWithEOO()) {
BSONElement e = i.next();
const char* fname = e.fieldName();
if (fields.count(fname)) {
b.append(e);
++n;
gotId = gotId || strcmp(fname, "_id") == 0;
if (n == N && gotId)
break;
} else if (strcmp(fname, "_id") == 0) {
b.append(e);
gotId = true;
if (n == N && gotId)
break;
}
}
if (n) {
*this = b.obj();
}
return n;
}
So, that's pretty what I have done now.
I am not familiar with the mongodb source code structure and its really a huge project for me to understand. Looking forward to a detailed To-Do list that I can follow to modify the code without too much knowledge is required about how mongodb works. But of course, any other type of information that is related is welcome. Thanks in advance.
In that 3rd code snippet you posted, replacing bool gotId = false with bool gotId = true may make it behave as you want - but it also may break things.
You mentioned the reason you began this is to improve storage performance - is removing one field really going to make a sizeable difference? I'd be surprised if it did. What's a lot more likely is that some functionality that you do desire will break (perhaps not now, perhaps a long time down the line at a point where you least expect it).
Warnings aside, you said you wanted :
a detailed To-Do list that I can follow to modify the code
It's unlikely you'll find someone familiar enough with the MongoDB source to the level where they could tell you if it's safe/unsafe and how to remove this field on StackOverflow - you're more likely to get a response by trying to contact the dev team, or at least people who add code to the open source effort. As a final warning though, it's unlikely you'll find anyone even there who'll take the time to list the steps. Modifications like this tend to require a large devotion of time to understand the source - there's no easy fix.
What you are trying to do right now is not going to work. _id is essentially the primary key and in many places in the code there is an assumption that the _id field is present (and of course unique). If you are not very familiar with the idea of primary keys, think of it as unique record identification in the database. No identification == no record.
What is the specific benefit that you're seeking? You should rephrase your question and ask people how to achieve that instead.
Good luck!

Can you rewrite this snippet without goto

Guys, I have the following code that is inside a big while loop that iterates over a tree. This is as fast as I can get this routine but I have to use a goto. I am not fundamentally against goto but if I can avoid them I would like to. (I am not trying to start a flame war, please.)
The constraints:
The current=current->child() is expensive (it's a shared_ptr) so I'd like to minimize the use of that operation at all cost.
After the operation current should be the last child it found.
cnt must count each child it encounters.
cnt++ will be replaced by some other operation (or several operations) and should only appear once :)
the code:
insideloopy:
cnt++;
if ( current->hasChild() )
{
current = current->child();
goto insideloopy;
}
Edit: Sorry guys, originally forgot to mention cnt++ should only appear once. It will be some kind of operation on the node, and should thus only be there one time. I'm also trying to avoid making that another function call.
Original answer
Assuming this is C or C++:
while (cnt++, current->hasChild())
{
current = current->child();
}
I'm not a big fan of the comma operator usually, but I don't like repeating myself either :)
Updated 'fun' answer
After learning that cnt++ is actually some multiline operation, this particular syntax would be less than ideal. Something more along the lines of your accepted answer would be better.
If you want to be really funky, this would also work:
do
{
cnt++;
} while (current->hasChild() && (current = current->child()));
Now I feel really dirty though, with my abusing the short circuiting on the && operator :)
Sane answer
Exercises in compactness aside and striving for readable code, I'm forced to conclude that one of the existing answers is best suited (I'm just including this for completeness' sake):
while (true)
{
cnt++;
if (!current->hasChild()) break;
current = current->child();
}
The while (true) will be optimized by the compiler into a regular infinite loop, so there is only one conditional statement (if you care about that).
The only thing going against this solution is if your node operation was a long piece of code. I don't mind infinite loops so much, as long as I can see where they terminate at a glance. Then again, if it were really long, it should be a function anyway.
cnt++;
while(current->hasChild())
{
cnt++;
current = current->child();
}
EDIT:
If you only want cnt++ to be in your code once:
while(true)
{
cnt++;
if(current->hasChild())
current = current->child();
else
break;
}
insideloopy:
cnt++;
if ( current->hasChild() )
{
current = current->child();
goto insideloopy;
}
I love infinite loops.
while (true) {
cnt++;
if (!current->hasChild()) break;
current = current->child();
}
Of course you can do it in many other ways (see other answers). do while, put the check in the while, etc. In my solution, I wanted to map nearly to what you are doing (an infinite goto, unless break)
You can use break to get out of the loop in the middle of the code:
while (true) {
cnt++;
if (!current->hasChild()) break;
current = current->child();
}
while (current->hasChild())
{
cnt++;
current = current->child();
}
Or am I missing something?
for(cnt++ ; current->hasChild() ; cnt++) {
current = current->child();
}
I'd investigate the possibility of making current->child() return NULL when it has no child if it doesn't already -- that seems the best possible result and leaving it undefined in this case seems error prone -- and then use:
for (; current; current = current->child())
{
cnt++;
}
No break statements:
notDone=true;
while(notDone){
cnt++;
if ( current->hasChild() ){
current = current->child();
} else {
notDone=false;
}
}

Checking lists and running handlers

I find myself writing code that looks like this a lot:
set<int> affected_items;
while (string code = GetKeyCodeFromSomewhere())
{
if (code == "some constant" || code == "some other constant") {
affected_items.insert(some_constant_id);
} else if (code == "yet another constant" || code == "the constant I didn't mention yet") {
affected_items.insert(some_other_constant_id);
} // else if etc...
}
for (set<int>::iterator it = affected_items.begin(); it != affected_items.end(); it++)
{
switch(*it)
{
case some_constant_id:
RunSomeFunction(with, these, params);
break;
case some_other_constant_id:
RunSomeOtherFunction(with, these, other, params);
break;
// etc...
}
}
The reason I end up writing this code is that I need to only run the functions in the second loop once even if I've received multiple key codes that might cause them to run.
This just doesn't seem like the best way to do it. Is there a neater way?
One approach is to maintain a map from strings to booleans. The main logic can start with something like:
if(done[code])
continue;
done[code] = true;
Then you can perform the appropriate action as soon as you identify the code.
Another approach is to store something executable (object, function pointer, whatever) into a sort of "to do list." For example:
while (string code = GetKeyCodeFromSomewhere())
{
todo[code] = codefor[code];
}
Initialize codefor to contain the appropriate function pointer, or object subclassed from a common base class, for each code value. If the same code shows up more than once, the appropriate entry in todo will just get overwritten with the same value that it already had. At the end, iterate over todo and run all of its members.
Since you don't seem to care about the actual values in the set you could replace it with setting bits in an int. You can also replace the linear time search logic with log time search logic. Here's the final code:
// Ahead of time you build a static map from your strings to bit values.
std::map< std::string, int > codesToValues;
codesToValues[ "some constant" ] = 1;
codesToValues[ "some other constant" ] = 1;
codesToValues[ "yet another constant" ] = 2;
codesToValues[ "the constant I didn't mention yet" ] = 2;
// When you want to do your work
int affected_items = 0;
while (string code = GetKeyCodeFromSomewhere())
affected_items |= codesToValues[ code ];
if( affected_items & 1 )
RunSomeFunction(with, these, params);
if( affected_items & 2 )
RunSomeOtherFunction(with, these, other, params);
// etc...
Its certainly not neater, but you could maintain a set of flags that say whether you've called that specific function or not. That way you avoid having to save things off in a set, you just have the flags.
Since there is (presumably from the way it is written), a fixed at compile time number of different if/else blocks, you can do this pretty easily with a bitset.
Obviously, it will depend on the specific circumstances, but it might be better to have the functions that you call keep track of whether they've already been run and exit early if required.