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].
Related
I am working on a vocabulary quiz app (French to English / English to French).
I need to check if what user types is what is expected.
Example : "Une machine à laver" --> Expected answer is "A washing machine".
The user can make many different sorts of mistakes such as spelling : "A watching machine", a word order mistake : "A machine washing" or a total mistake "A garden tool".
I have managed to deal with the checking when the expected word is just one word : "un jardin : a garden".
But with compound words, the issue of words order comes up.
I split the Strings into two lists :
_expectedAnswer contains the different elements of the answer : [washing,machine]
_typedAnswer contains the different elements of what the user typed : [machine, washing] or [watching,machine] or [washing,machine], or [a,washing,machine] (Here, the user added an article before the noun, which shouldn't be seen as a mistake).
At the end, the algorithm must tell the user what type of mistakes he has done :
Word order mistake.
Word order is correct, but one or all elements contain spelling problems.
word order mistake + spelling problems
completely wrong.
For the spelling check I use the levenstein algorithm. And it is satisfactory.
So first I thought I should check if _typedAnswer contains all the elements of _expectedAnswer.
-> Should check if the sequence of elements is the same : the order is OK, and no spelling pb.
-> Elements are all present but sequence is not respected : Problem with word order, no spelling mistakes.
-> Elements are not present
--> Then we check if "similar elements" are present (which would indicate user made a spelling mistake) .... and check the order of elements too...
Any advice to help me work out this algorithm ?
I have read a lot about all the functions linked to dart lists, but I have to admit, that I kinda got lost on which one would be pertinent to use...
I took the the last hour to solve your problem. I made it easy for you to test it and understand what is the logic behind it.
In order to use it in your code you have to put the control-flow statements into a separate function and pass the list of user input elements as well as the list of expected result elements to it.
For BOTH lists you need each word as a String, which is trimmed from all whitespaces!
I believe you are able to do that part, as described in your question already. I would deeply appreciate if you can upvote for my effort and accept the answer, if it helped you out.
EDIT: Requires an official dart package on pub.dev
Add a line like this to your package's pubspec.yaml:
dependencies:
collection: ^1.15.0
Here is the logic, please copy & test in inside DartPad:
import 'package:collection/collection.dart';
void main() {
List expectedAnswer = ["one", "two", "three"];
List listWrongSpelling = ["oe", "two", "three"];
List listWrongSpellings = ["oe", "twoo", "three"];
List listWrongOrder = ["two", "one", "three"];
List listEntirelyWrong = ["dskfrm", "twhoo", "111", "tedsf"];
List listIdentical = ["one", "two", "three"];
// FYI: Checks if there is any kind of mistake (is used below dynamically)
Function eq = const ListEquality().equals;
final result1 = eq(expectedAnswer, listWrongSpelling); // false
final result2 = eq(expectedAnswer, listWrongSpellings); // false
final result3 = eq(expectedAnswer, listWrongOrder); // false
final result4 = eq(expectedAnswer, listEntirelyWrong); // false
final result5 = eq(expectedAnswer, listIdentical); // true, the perfect answer
// print(result1);
// print(result2);
// print(result3);
// print(result4);
// print(result5);
// CHECK IF ANSWER IS PERFECT:
bool isPerfect(List toBeChecked, List expectedResult) {
Function eq = const ListEquality().equals;
return eq(toBeChecked, expectedResult) ? true : false;
}
// ONLY EXECUTE OTHERS IF THERE IS AN MISTAKE:
// Checks for word order mistake
// Condition: Must contain each element with identical value, hence only order can be wrong
bool checkOrder(List toBeChecked, List expectedElements) {
List<bool> listOfResults = [];
for (var element in toBeChecked)
{
bool result = expectedElements.contains(element);
listOfResults.add(result);
}
// If one element is not in expectedElements return false
return listOfResults.contains(false) ? false : true;
}
// Checks for any spelling errors
bool checkSpelling(List toBeChecked, List expectedElements) {
// Once this function gets executed there are only two errors possible:
// 1st: Unexpected elements (e.g. an article) (and possibly spelling errors) >> return false
// 2nd: No unexpected elements BUT spelling errors >> return true
return toBeChecked.length == expectedElements.length ? true : false;
}
// FINAL RESULT
String finalResult = "";
// Please try out the other lists from above for all possible cases!
bool isPerfectAnswer = isPerfect(listIdentical, expectedAnswer);
bool isWordOrderIncorrect = checkOrder(listIdentical, expectedAnswer);
bool isSpellingIncorrect = checkSpelling(listIdentical, expectedAnswer);
if(isPerfectAnswer) {
// The user entered the correct solution perfectly
finalResult = "Everything is correct!";
} else if(isWordOrderIncorrect) {
// CHECKS IF ONLY WORD ORDER IS WRONG
// false means there are unexpected elements in the user input
// true there are no unexpected elements, but the order is not correct, since the first check failed!
// Is true the case, then both lists contain the same elements.
finalResult = "Your word order is incorrect!";
} else if(isSpellingIncorrect) {
// Either unexpected elements (lenght of lists must differ) OR misspelled (same length, error in spelling)
finalResult = "Your spelling is incorrect!";
} else {
// If it gets here, the input has:
// Unexpected elements (e.g. an article), possibly spelling errors AND possibly order mistakes
// You could check if the order is correct, but what´s the point to write complex logic for that,
// knowing there are also unexpected elements, like additional prepositions or wrong words, in addition
// to spelling mistakes.
// Just show your user a message like this:
finalResult = "Unfortunatelly your answer is incorrect. Try again!";
}
// PRINT RESULT:
print(finalResult);
}
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.
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?
The error I'm getting is error: expected ' ; ' before ' { ' token
I tried fixing the code by adding ; after if (thisisanumber==5) as well as after else (thisisanumber!=5). While this solves the first error it creates another error that says error: ' else ' without a previous ' if '. I'd really love to know what error I've made in writing the code, thanks.
Here is my code:
#include <iostream>
using namespace std;
int main()
{
int thisisanumber;
cout<<"Whats the Password?: ";
cin>> thisisanumber;
cin.ignore();
if (thisisanumber==5) {
cout<<"You've discovered the password! Wow, you're a genious you should be proud./n";
}
else (thisisanumber!=5) {
cout<<"You've failed in knowing the password and therefore cannot enter, leave and do not come back. Goodbye!/n";
}
cin.get();
}
You're missing a keyword if:
else if (thisisanumber!=5) {
^^
Alternately, since the opposite condition to thisisanumber == 5 is that thisisanumber is not 5, you don't need the condition:
else {
You don't need another condition as there are only two cases - just use else { ... } and it will catch all cases in which thisisanumber==5 is false.
The structure of an if statement is:
if (condition) { ... }
else if (another condition) { ... }
// ... more conditions
else { ... all cases in which no previous condition matched end up here ... }
... but the else if and else parts are always optional.
What happens is the compiler looks at the following:
else (thisisanumber!=5) {
and thinks to itself:
"OK, here's else. Is the next token if? No. Ok, so this is an else clause, and the next thing is what to do in the else-case. Is the next token {? No. Ok, so in the else-case, we execute a single statement, instead of a block. Is the next token (? Yes. Ok, so our statement is wrapped in parentheses... [insert here: the rest of the thought process for interpreting an expression that's wrapped in parentheses] Ok, there's the matching ). Whew. Now let's just match up the ; for this statement... wait, what's this? A {! That's not right."
The compiler is reading the code one token at a time, left to right. It does not report an error at the point where, in a logical sense that humans understand, the error actually is. It reports an error at the point where, by reading the code one token at a time, left to right, it is first able to detect that something is wrong.
It would be legal to write else (thisisanumber!=5);. That would mean "if the number is not equal to 5 (because the if test failed), then check if the number is not equal to 5, and do nothing with the result of that comparison". Meaningless, but legal. It would also be legal to write else if (thisisanumber!=5) {...}, which is presumably what you meant. That would mean "if the number is not equal to 5 (because the if test failed), and the number is not equal to 5, then do this stuff inside the {}". But this is redundant: given that something is not equal to 5, it is guaranteed to be not equal to 5, so there is no point in specifying the test twice. So we should just write else {...}.
"else" is really a shorter word for "otherwise", and has that purpose in C++ as well.
Update:
Thanks Ben, I decided to copy the URL to another structure and modify that one with StructUpdate(). Here's the code if anyone's interested (specific to my application, but you can edit the lines with comments to get a useful function).
function rebuildURL(key, value)
{
var URLstring = "";
var VarCount = 0;
var tmpURL = duplicate(URL);
var VarSeparator = "";
structUpdate(tmpURL, arguments.key, arguments.value);
for (key in tmpURL)
{
if (tmpURL[key] neq "" and tmpURL[key] neq "10000" and tmpURL[key] neq "1") `<!--- remove the tmpURL[key] neq "10000" and "1"--->`
{
if (VarCount neq 0)
{
VarSeparator = "&";
}
else
{
VarSeparator = "";
}
URLstring = URLstring & VarSeparator & "#Lcase(key)#" & "=#Lcase(tmpURL[key])#";
VarCount = VarCount + 1;
}
}
structClear(tmpURL); `<!---not sure if this is necessary, but probably can't hurt unless you are processing thousands of links --->`
return(URLstring);
}
Thanks again!
Scott
Hey guys,
I'm writing a custom function to rework the URL for links in my pages, and I'm getting the following error:
Complex object types cannot be converted to simple values.
The expression has requested a variable or an intermediate expression result as a simple value, however, the result cannot be converted to a simple value. Simple values are strings, numbers, boolean values, and date/time values. Queries, arrays, and COM objects are examples of complex values.
The most likely cause of the error is that you are trying to use a complex value as a simple one. For example, you might be trying to use a query variable in a cfif tag.
The error occurred in C:\ColdFusion8\wwwroot\pascalnew\turbos.cfm: line 8
Called from C:\ColdFusion8\wwwroot\pascalnew\turbos.cfm: line 108
Called from C:\ColdFusion8\wwwroot\pascalnew\turbos.cfm: line 93
Called from C:\ColdFusion8\wwwroot\pascalnew\turbos.cfm: line 1
Called from C:\ColdFusion8\wwwroot\pascalnew\turbos.cfm: line 1
6 : URLvar = "#URL#";
7 : switch(param)
8 : {
9 : case 'mfr':
10 : {
Here's my function code:
<cfscript>
function SetURL(param, paramval)
{
URLvar = "#URL#";
switch(param)
{
case 'mfr':
{
IF (URLvar contains "mfr")
{
REReplaceNoCase(URLvar, "mfr=^[^\&]", "mfr=#paramval#", "All");
}
break;
}
}
return(URLvar);
}
</cfscript>
Here's what I was testing it with:
<cfset urlvar = SetUrl("mfr", "edwards")>
<cfdump var="#urlvar#">
How is "mfr" a complex variable??
Thanks,
Scott
When you use CFScript, some versions report the beginning of the block as the line with the error.
When you assign "#URL#" to URLVar, you are creating a pointer to the URL scope. then, you attempt to use the contains operator on it. Contains, however, only compares two simple values.
So, your attempt to reference a complex value as a scalar actually comes here:
IF (URLvar contains "mfr")
{
REReplaceNoCase(URLvar, "mfr=^[^\&]", "mfr=#paramval#", "All");
}
At a guess, you are trying to look at the URL itself, not the URL scope. You can assemble this from parts of the CGI scope, including SERVER_NAME, SCRIPT_NAME, AND QUERY_STRING (or you can look at the individual part you need).
Added: If you want to know if a variable is passed in the url, I think you are overthinking this. Let's say you have a param and a paramval to replace it with. You could do it like this:
function paramReplace(param, paramVal, scope)
{
if(structkeyexists(arguments.scope, arguments.param))
{
arguments.scope[arguments.param] = arguments.paramVal;
}
}
paramReplace("mfr", "fred", URL);
This simply uses structKeyExists to find out if that variable exists in the appropriate scope, then replaces the value if it does. If you need to rebuild your actual query string, you can do so later. This avoids scenarios where you get bad data if your query string contains something like "zone=mfr".
I've not tested this -- it's off the cuff -- so it may need tweaking, but it should get you started.