programmatic insert of code into function.
Mike German
I have a function with a number of if_endthen statements. The expressions that I use in the statements need to be changed occassionally and at the moment I edit them manually. Is it possible to use a string containing the text to be used within the if expression and to translate that text so that it operates within the code.
if (x=1 && b=2)
// do something
endif
string expression ="(x=1 && c=2)"
// do something
endif
string expression ="(x=1 && c=2)"
Above is an example of what I would like to be able to do. At the moment I have a, say, the expression as shown, and I would like to program in someway so that the string or textwave item containing the replacement expression into the original code. I am not a professional programmer (as you will have guessed) but I think it is called parsing?
Would you expect these statements to be infinite in variations or can you expect them to be finite in how many you need? I can suggest in the former case that you may have to resort to a function that is called with the string using Execute. I might suggest in the latter case that you could hard code the options entirely and simply comment / uncomment them as needed during editing.
March 12, 2024 at 01:42 pm - Permalink
I use the if statements as data filters which need testing and optimising for each experiment. At present there are 10 statements and some 20 odd variables which are usually combined and have individual limits. So, it is the former of your two suggestions I would need to use.
I have been using the comment / uncomment method but as each of the statements I wish to change could be entirely different I sought another way.
March 13, 2024 at 03:09 am - Permalink
I am still not sure what you want to do. I can guess in two different directions. Can you provide a minimum working example (MWE) of code block A that you want to change to code block B without having to make the change using manual editing?
March 13, 2024 at 07:07 am - Permalink
/I'm not quite sure of your workflow, but could you use something along these lines? ...
variable a, b
if (a < b)
return 1
else
return 0
endif
End
Function DoStuff()
variable v1, v2
v1 = 1
v2 = 2
if (myCondition(v1, v2))
print "expression is true"
else
print "expression is false"
endif
End
You rewrite the function myCondition (which could be at the top of the given procedure window), and then the main functions would call this when it needs to. This saves having to look through many lines of code to find the desired if-statements to change.
If you want to programmatically change the condition function, then maybe FUNCREFs could help?
March 13, 2024 at 07:46 am - Permalink
JJ a little difficult to do as I don't know what yopu have in mind. So, I give you an edited/tidied section of the code I use to give you an idea of the stats waves (at the top of this snippet) that I may want to use in the if statements (conjectures 0 to 9) Conjecture 7 and 8 show the type of commenting out that I make. All the stats wave have the same number of points (number of items) in the for.. endfor loop and the wave itemType[numberofItems][10] contains the result of the conjecture test
wave Tstart = $StatsDFN +":"+"Tstart"
wave StartPnt = $StatsDFN +":"+"StartPnt"
wave Tend = $StatsDFN +":"+"Tend"
wave EndPnt = $StatsDFN +":"+"EndPnt"
wave Duration = $StatsDFN +":"+"Duration"
wave ItemPnts = $StatsDFN +":"+"ItemPnts"
wave Gap = $StatsDFN +":"+"Gap"
wave SNRmax = $StatsDFN +":"+"SNRmax"
wave SdBmax = $StatsDFN +":"+"SdBmax"
wave SdBsd = $StatsDFN +":"+"SdBsd"
wave SdBmean = $StatsDFN +":"+"SdBmean"
wave Fstart = $StatsDFN +":"+"Fstart"
wave Fend = $StatsDFN +":"+"Fend"
wave Fmax = $StatsDFN +":"+"Fmax"
wave Fmin = $StatsDFN +":"+"Fmin"
wave Fmean = $StatsDFN +":"+"Fmean"
wave Fsd = $StatsDFN +":"+"Fsd"
wave PeakNum = $StatsDFN +":"+"PeakNum"
wave HEpnts = $StatsDFN +":"+"HEpnts"
wave HEslope = $StatsDFN +":"+"HEslope"
/// Test various conjectures concerning Item characteristics
for (i=0;i<numOfItems;i+=1)
// conjecture 0
if(Fmin[i]<10 && Fmin[i]>-100)
itemType[i][0] = 1
endif
// conjecture 1
if(SdBsd[i] > 4.5 && Fmean[i] <800)
itemType[i][1] = 1
endif
// conjecture 2
if(HEpnts[i] >=3 && HEslope[i] <-600 && Fmin[i]<100 && Fmin[i]>-100)
itemType[i][2] = 1
endif
// Conjecture 3
if(PeakNum[i] >=0 && SdBsd[i]>4)
itemType[i][3] = 1
endif
// conjecture 4
if(ItemPnts[i]>500 && SdBsd[i]<4)
itemType[i][4] = 1
endif
// conjecture 5
if(itemType[i][1] == 1 && itemType[i][2]==1 && ItemPnts[i]>60)
itemType[i][5] = 1
endif
// conjecture 6
if(itemType[i][1] == 1 && itemType[i][2]==1 && ItemPnts[i]<=10)
itemType[i][6] = 1
endif
// conjecture 7
// if(HEpnts[i] >=5 && HEslope[i] <-600 && Fmin[i]<100 && Fmin[i]>-100)
// if(HEpnts[i] >=5 && HEslope[i] <-600 && Fmin[i]<100 && Fmin[i]>-50)
if(Fend[i]>100)
itemType[i][7] = 1
endif
// conjecture 8
if(PeakNum[i] >=6)// && SdBsd[i]>4)
itemType[i][8] = 1
endif
// conjecture 9
if(Fmin[i]>250 && SdBsd[i]<4)
itemType[i][9] = 1
endif
endfor
March 13, 2024 at 07:51 am - Permalink
In reply to /I'm not quite sure of your… by KurtB
Another thought has come to me - perhaps you could use ProcedureText() to extract the code, swap in the changed line for the if statement, save, and then something like Execute "COMPILEPROCEDURES" (possibly with a /P, and after Execute/P "LOADFILE [filename.ipf]" ?
March 13, 2024 at 08:21 am - Permalink
OK. Clearer now. Thanks.
Write your conjectures as separate functions. Use #define-#ifdef compiler directives.
Function test_0(wave Fmin, variable pp)
variable vrtn
vrtn = ((Fmin[pp] < 10) && (Fmin[pp] > -100)) ? 1 : 0
return vrtn
end
Function test_7(wave HEpnts, wave HEslope, wave Fmin, wave Fend, variable pp)
variable rtn
#ifdef Code7A
vrtn = ((HEpnts[pp] >= 5) && (HEslope[pp] < -600) && (Fmin[pp] < 100) && (Fmin[pp] > -100)) ? 1 : 0
#endif
#ifdef Code7B
vrtn = ((HEpnts[pp] >= 5) && (HEslope[pp] < -600) && (Fmin[pp] < 100) && (Fmin[pp] > -50)) ? 1 : 0
#else
vrtn = (Fend[pp] > 100) ? 1 : 0
#endif
return vrtn
end
// replace the explicit for loop with implicit for loop
itemType[][0] = test_0(Fmin, p)
itemType[][7] = test_7(HEpnts, HEslope, Fmin, Fend, p)
This allows you to keep each conjecture clean in its own regard. It also allows you to change something simpler ... Code7A vs Code7B versus no definition (or Code7C). Finally, moving the explicit for-loop to implicit should speed up the processing.
March 13, 2024 at 08:35 am - Permalink
Thanks JJ.
I'm sure this will help Seperate functions and implicit loops I will try and any speed improvement will be worthwhile. However, I am not familiar with the structure of compiler directives and how to use them. From a quick look at the excellent Igor help I will need to swot up on conditional compilations!
March 13, 2024 at 10:03 am - Permalink
In reply to Another thought has come to… by KurtB
Thanks Kurt
I will need to think about that ... not immediately apparent to me how that would work.
March 13, 2024 at 10:05 am - Permalink
What Kurt was referring to was dynamically changing the content of your procedure / code to modify what the functions are doing. I think it would be impossible or at least instable to modify the procedure file which you are executing at the same time. You can do something like this for modifying a different procedure file or the main procedure window, however. An example for the latter can be found here:
https://www.wavemetrics.com/forum/general/create-automatically-override…
I don't think this is the path you should follow. I think what JJ proposed is practical and safe for your case.
March 20, 2024 at 09:44 pm - Permalink
What chozo says is quite sound. Don't try to write self-modifying code. That way lies brittle code and madness. I know this from personal experience.
A possible option that hasn't been mentioned yet is to use an override function for your constantly changing conditional. Write the conditional as something like
// do something
endif
And in that same procedure file, define a version of the function:
return (A>1 && B>2)
end
In the main procedure window, write your currently desired version:
return (A<1 && B>1.5)
end
Read about override functions: DisplayHelpTopic "Function Overrides"
March 21, 2024 at 09:28 am - Permalink