I have a small dxl script and I need to return the number of assigned positions from an array of, let's say, size 20 in which only 10 positions are assigned.
I tried to use noError() and lastError() functions, but after lastError() is called, the script is halted and I can't continue the execution.
Here's my code:
int returnArrayLength(string array[]){
int lengthOfArray = 0,i = 0;
for (i=0; i < sizeof array ; i++){
noError()
if (!null array[i]){
lengthOfArray++
print lengthOfArray
}
if (!null lastError()){
print "Exception caught!" // not printed
break
}
}
return lengthOfArray
}
string labels[6]
labels[0] = "label0"
labels[1] = "label1"
labels[2] = "label2"
labels[3] = "label3"
print returnArrayLength(labels) // not printed
The above code prints the following:
1
2
3
4
How can I resume the execution after the lastError() function is called ?
This was tougher than I thought it would be!
So, as it turns out, an unassigned element error halts the DXL program entirely. So what do we need to do?
Well, we need to run a snippet of code, in it's own environment, and let it crash if it needs to!
To do so, we need to create an eval_, pass it our array, and then have it return_ (which won't be executed if the eval_ fails)
Take a look:
int returnArrayLength(string array[]){
int lengthOfArray = 0,i = 0;
for (i=0; i < sizeof array ; i++){
string scode = "noError()
string ( &passedAr)[] = (addr_ "( ( addr_ array ) int ) ")
string s = passedAr["i"]
lastError()
return_ \"Y\""
if ( ( eval_ scode ) == "Y" ){
lengthOfArray++
print lengthOfArray
} else {
print "Exception caught!" "\n"
break
}
}
return lengthOfArray
}
string labels[6]
labels[0] = "label0"
labels[1] = "label1"
labels[2] = "label2"
labels[3] = "label3"
print returnArrayLength(labels)
What a fantastic little problem.
Resources I used to help solve this:
How to pass an array into an eval_
eval_ , addr_ , and memory leaks
Testing for unassigned variables - This one doesn't quite work because of the nature of arrays, at least as far as I could tell!
In any case, thanks for the challenge!
Related
This is my main.dart:
import 'edgecases.dart';
main () {
var card = edgecases(0)['input']['cards'];
var query = edgecases(0)['input']['query'];
var result = locate_card(edgecases(0)['input']['cards'], edgecases(0)['input']['query']);
var output = edgecases(0)['output'];
print("Cards:- $card");
print("Query:- $query");
print("Output:- $result");
print("Actual answer:- $output");
}
And this is my edgecases.dart:
edgecases ([edgecasenumber = null]) { //You may make it required, I provided a null as default to check if my syntax is going right.
List tests = [];
var edge1 = {'input': {
'cards': [13, 11, 10, 7, 4, 3, 1, 0],
'query': 1
}, 'output': 6};
tests.addAll([edge1]);
if (edgecasenumber == null){ // This if is useless here so you may
return 'Null type object coud not be found.';
} else {
return tests.elementAt(edgecasenumber); // Indexing in dart also starts with 0.
}
}
locate_card (List cards, int query){
int lo = 0;
int hi = cards.length - 1;
print('$lo $hi');
while (lo <= hi) {
//print('hello'); Uncomment to see if it is entering the loop
var mid = (lo + hi) ~/ 2;
var mid_number = cards[mid];
print("lo:$lo ,hi:$hi, mid:$mid, mid_number:$mid_number");
if (mid_number == query){
return mid;
} else if (mid_number < query) {
hi = mid - 1;
} else if (mid_number > query) {
lo = mid + 1;
};
return -1; //taking about this line
};
}
[I have cut short the code here so you may find some things as unnecessary so just ignore it XD]
Actually I am trying to implement binary search here(I have previously successfully implemented it in python, I am implementing in dart to learn the language.)
On testing it with first edge case(that is on running the command dart main.dart), I found that it is returning the value -1 which was wrong, so I tried commenting the return -1; line in edgecases.dart file to see what happens as it was made to handle another edge case(edgecase if the list is empty, here I have removed that for simplicity). I am not able to understand why it is returning -1 if it gives the right value on commenting that line. Any possible explainations and solutions?
Thanks in advance!
You almost did it right. Just place the return -1; after the while loop's closing brace at the very end of locate_card.
I'm currently trying to run Export to PDF script, however when I try running it in DOORS ver 9.6.1, I get a couple of errors.
Line 8: char c = str[i]; contains a syntax error
Any thoughts on how I can resolve this issue?
string makeCaption(Buffer& str)
{
setempty(tempBuf);
int i = 0;
{
for(i = 0; i < length(str); ++i)
char c = str[i];
if('\n' != c) && '\\' != c)
{
tempBuf += c;
}
}
escapeSpecialLaTeXCharacters(tempBuf);
return stringOf(tempBuf);
}
Seems to me like copy/paste problems. When you compare your code with the original you might notice that you moved line 6 with the sole { one line up. If you put it back where it belongs i.e. after the line "for(...)", the code works
I have skip list contains an ADC, FIFO, DAC, FILO etc.
I want to know whether these words are used in the entire module or not .if used in the module should return the unused words.
I have a program but it is taking too much time to execute.
Please help me with this.
Here is the code :
Skip Search_In_Entire_Module(Skip List)
{
int sKey = 0
Skip sList = create()
string data = ""
string objText1
Object obj
for data in List do
{
int var_count = 0
for obj in m do
{
objText1 = obj."Object Text"
if objText1!=null then
{
if (isDeleted obj){continue}
if (table obj) {continue}
if (row obj) {continue}
if (cell obj) {continue}
Buffer buf = create()
buf = objText1
int index = 0
while(true)
{
index = contains(buf, data, index)
if(0 <= index)
{
index += length(data)
}
else
{
var_count++
break
}
}
delete(buf)
}
}
if (var_count ==0)
{
put(sList,sKey,data)
sKey++
}
}
return sList
}
Unused_Terminolody_Data = Search_In_Entire_Module(Terminology_Data)
Just wondering: why is this in a while loop?
while(true)
{
index = contains(buf, data, index)
if(0 <= index)
{
index += length(data)
}
else
{
var_count++
break
}
}
I would instead just do:
index = contains ( buf, data )
if ( index == -1 ) {
var_count++
}
buf = ""
I would also not keep deleting and recreating the buffer. Create the buffer up where you create the object variable, then set it equal to "" to clear it, then delete it at the end of the program.
Let me know if this helps!
Balthos makes good points, and I think there's a little more you could do. My adaptation of your function follows. Points to note:
I implemented Balthos's suggestions (above) of taking out the
'while' loop, and buffer creation/deletion.
I changed the function signature. Given that Skip lists are passed
by reference, and must be created and deleted outside the function
it's syntactically confusing (to me, anyway) to return them from a
function. So, I pass both skip lists (terms we're seeking, terms not
found) in as function parameters. Please excuse me changing variable
names - it helped me to understand what was going on more quickly.
There's no need to put the Object Text in a string - this is
relatively slow and consumes memory that will not be freed until
DOORS exits. So, I put the Object Text in a buffer earlier in the
function, and search that. The 'if (!null bufObjText)' at my line 34
is equivalent to your 'objText1!=null'. If you prefer, 'if
(bufObjText != null)' does the same.
The conditional 'if (var_count ==0)' is redundant - I moved it's
functions into an earlier 'if' block (my line 40).
I moved the tests for deleted, table, row and cell objects up, so
that they occur before we take the time to fill a buffer with object
text - so that's only done if necessary.
Item 2 probably isn't going to have a performance impact, but the others will. The only quesiton is, how large?
Please let us know if this improves the running time over what you currently have. I don't have a sufficiently large set of sample data to make meaningful comparisons with your code.
Module modCurrent = current
Skip skUnused_Terminology_Data = create
Skip skSeeking_Terminology_Data = create()
put (skSeeking_Terminology_Data, 0, "SPONG")
put (skSeeking_Terminology_Data, 1, "DoD")
void Search_In_Entire_Module(Skip skTermsSought, skTermsNotFound)
{
Object obj
Buffer bufObjText = create()
int intSkipKey = 0
int index = 0
string strSkipData = ""
for strSkipData in skTermsSought do
{
int var_count = 0
bool blFoundTerm = false
for obj in modCurrent do
{
if (isDeleted obj){continue}
if (table obj) {continue}
if (row obj) {continue}
if (cell obj) {continue}
bufObjText = obj."Object Text"
if (!null bufObjText) then
{
Regexp re = regexp2 strSkipData
blFoundTerm = search (re, bufObjText, 0)
if ( blFoundTerm ) {
put(skUnused_Terminology_Data, intSkipKey, strSkipData)
intSkipKey++
}
bufObjText = ""
}
}
delete (bufObjText)
}
Search_In_Entire_Module (skSeeking_Terminology_Data, skUnused_Terminology_Data)
string strNotFound
for strNotFound in skUnused_Terminology_Data do
{
print strNotFound "\n"
}
delete skUnused_Terminology_Data
delete skSeeking_Terminology_Data
The problem is that when the i in the for loop reaches 15, I get an Array out of range error.
What I want to achieve is on every tick to check every Symbol in the MarketWatch and in each Symbol to check the current bar ( PERIOD_M5 ) and the previous one if there is a gap.
void OnTick()
{
int size = ArraySize( Symbols );
for( int i = 0; i < size; i++ )
{
int current_bar_index = iHighest( Symbols[i], PERIOD_M5, MODE_HIGH, 1, 0 );
int previous_bar_index = iHighest( Symbols[i], PERIOD_M5, MODE_HIGH, 1, 1 );
int current_bar_index_low = iLowest( Symbols[i], PERIOD_M5, MODE_LOW, 1, 0 );
int previous_bar_index_low = iLowest( Symbols[i], PERIOD_M5, MODE_LOW, 1, 1 );
double current_high = High[ current_bar_index];
double previous_high = High[previous_bar_index];
double current_low = Low[ current_bar_index_low];
double previous_low = Low[ previous_bar_index_low];
if ( current_low > ( previous_high + 0.00002 )
|| current_high < ( previous_low - 0.00002 )
)
{
Print( "There is a gap" );
}
}
}
Symbols[] is the array containing all the symbols. I loop through it and pass the current Symbol and get the index for the current bar and the previous one and then simply check if there is a gap.
The first problem is that passing every Symbol doesn't work. It gets only one and that's it. How can I achieve that and also, why I get an Array out of range error?
Let's start with the Array out of range error:
Given the MCVE was not present, let's assume, there is some fair declaration of the MQL4 code in the header or something like that.
So to diagnose this, add a trivial debug tool:
string SymbolsARRAY[] = { ..., // be carefull, some Brokers
..., // have quite strange names
...
};
for ( int cellPTR = 0;
cellPTR < ArraySize( SymbolsARRAY );
cellPTR++
)
PrintFormat( "%s[%d] = %s",
"SymbolsARRAY",
cellPTR,
SymbolsARRAY[cellPTR]
);
and post here the output.
Next, the GAP detection:
if you would not mind, checking a pair of M5-Bars for a GAP on each and every price QUOTE message arrival, is quite devastating the MQL4 computing resources. The GAP may principally appear only upon a new Bar starts ( and yet may disappear, during the Bar duration ).
Let's detect the initial GAP-condition ( it is similar to engulfing detection ):
if ( iLow( SymbolsARRAY[cellPTR], PERIOD_M5, 1 ) > iHigh( SymbolsARRAY[cellPTR], PERIOD_M5, 0 )
|| iHigh( SymbolsARRAY[cellPTR], PERIOD_M5, 1 ) < iLow( SymbolsARRAY[cellPTR], PERIOD_M5, 0 )
)
Print( "Initial GAP detected" );
Using this inside a detection of a new bar event may look like this:
void OnTick(){
// -----------------------------------------------------------------
// MINIMALISTIC CONTEXT-AWARE GAP DETECT/REMOVE
// -----------------------------------------------------------------
static bool aCurrentGAP = False;
static datetime aCurrentBAR = Time[0];
if ( aCurrentBAR != Time[0] ){
aCurrentBAR = Time[0];
// testInitGAP .........................present?
aCurrentGAP = testInitialGAP_onNewBarEVENT();
}
else {
if ( aCurrentGAP ){
// testInitGAP .....................disappeared?
aCurrentGAP = testInitialGAP_DISAPPEARED();
}
}
// -----------------------------------------------------------------
// MAIN COMPUTING & TRADING DUTIES OF EA-MQL4-CODE
// -----------------------------------------------------------------
...
}
about the error - when you receive it, it also can see the address of the code that generates it: number of line and symbol number in that line
about Symbol - as you may know, in MQL5 you can select all symbols from the market watch, in MQL4 such option is not available, as far as I remember, so I suspect your array of symbol names is empty or sth like that.
Could you show how you initialized that array? A correct way is the following one:
string Symbol[]={"EURUSD","AUDUSD","GBPUSD"};
also your code doesn't make any sense - when you select iHighest(*,*,*,i,j) - that means that EA-code checks i-elements, starting from j-th element ( 1, 0 ) means a current bar only, ( 1, 1 ) means to select just 1 bar, starting from bar 1, so still only 1 Bar is used.
For that it is much easier to have
double cur_high = iHigh( Symbol[i], 5, 0 ),
prev_high = iHigh( Symbol[i], 5, 1 );
local function fShallowCopy(tData)
local tOutput = {}
for k,v in ipairs(tData) do
tOutput[k] = v
end
return tOutput
end
local function fLexTblSort(tA,tB) --sorter for tables
for i=1,#tA do
if tA[i]~=tB[i] then
return tA[i]<tB[i]
end
end
return false
end
function fBWT(tData)
--setup--
local iSize = #tData
local tSolution = {}
local tSolved = {}
--key table--
for n=1,iSize do
tData[iSize] = fRemove(tData,1)
tSolution[n] = fShallowCopy(tData)
end
table.sort(tSolution,fLexTblSort)
--encode output--
for i=1,iSize do
tSolved[i] = tSolution[i][iSize]
end
--finalize--
for i=1,iSize do
if fIsEqual(tSolution[i],tData) then
return i,tSolved
end
end
return false
end
Above is my current code for achieving BWT encoding in Lua. The issue is because of the size of the tables and lengths of loops it takes a long time to run. For a 1000 character input the average encoding time is about 1.15 seconds. Does anyone have suggestions for making a faster BWT encoding function?
the biggest slowdowns appear to be in fLexTblSort and fShallowCopy. I have included both above the BWT function as well.
If I see right, your algorithm has complexity O(n^2 log n), if the sort is quicksort. The comparator function fLexTblSort takes O(n) itself for each pair of values you compare.
As I checked with my implementation from few years back, I see possible space to improve. You create all the possible rotations of the tData, which takes also a lot of time. I used only single data block and I stored only starting positions of particular rotations. You also use a lot of loops which can shrink into less.
Mine implementation was in C, but the concept can be used also in Lua. The idea in some hybrid pseudocode between your Lua and C.
function fBWT(tData)
local n = #tData
local tSolution = {}
for(i = 0; i < n; i++)
tSolution[i] = i;
--table.sort(tSolution, fLexTblSort)
quicksort(tData, n, tSolution, 0, n)
for(i = 0; i < n; i++){
tSolved[i] = tData[(tSolution[i]+n-1)%n];
if( tSolution[i] == 0 )
I = i;
}
return I, tSolved
end
You will also need your own sort function, because the standard does not offer enough flexibility for this magic. Quicksort is a good idea (you might avoid some of the arguments, but I pasted just the C version I was using):
void swap(int array[], int left, int right){
int tmp = array[right];
array[right] = array[left];
array[left] = tmp;
}
void quicksort(uint8_t data[], int length, int array[], int left, int right){
if(left < right){
int boundary = left;
for(int i = left + 1; i < right; i++){
if( offset_compare(data, length, array, i, left) < 0 ){
swap(array, i, ++boundary);
}
}
swap(array, left, boundary);
quicksort(data, length, array, left, boundary);
quicksort(data, length, array, boundary + 1, right);
}
}
The last step is your own comparator function (similar to your original, but working on the rotations, again in C):
/**
* compare one string (fixed length) with different rotations.
*/
int offset_compare(uint8_t *data, int length, int *array, int first, int second){
int res;
for(int i = 0; i < length; i++){
res = data[(array[first]+i)%length] - data[(array[second]+i)%length];
if( res != 0 ){
return res;
}
}
return 0;
}
This is the basic idea I came up with few years ago and which worked for me. Let me know if there is something not clear or some mistake.