The python file multiplies the output from sofistik and writes it to a dat file from_py.dat which I then want Sofistik to read again
Python file:
sofi = float(open('from_sofi.dat').read())*5
with open('from_py.dat','w') as f:
f.write(f'let#from_py {sofi}')
The idea is that the Sofistik file should perform the tasks line by line, i.e.:
Write output file from_sofi.dat
Run python file test.py
Read input file from_py.dat
However, as I have come to understand Sofistik starts by scanning for #include tags and attempts to include these files which haven’t been generated yet.
As such, I have to manually run each of the three tasks in order to force sofistik to read the file in a proper order.
Is there a way to force sofistik to read the file line by line?
PS:
If there already is a from_py.dat file present in the working directory, it does run, but as it reads the #include before it runs task1, any changes I make in task1 is not included in task3 unless I run everything manually.
#Include works like a preprocessor instruction, i.e.
wps (the calculation window or sps in batch mode) scans through your file
copy/pastes all #includes
Checks for obvious mistakes (missing ends, #enddef, Endif, endloop, etc)
The result is a parsed file, that the program actually runs
If you look at the “input data” in your report, you see the parsed code (no #includes present).
Therefore you can not #include anything that is generated during calculation.
There are two workarounds for this:
Sofistiks own variant that is used in CSM:
+Apply something.dat
With this a file generated at run time can be included in the calculation.
Drawback: It has to be a “complete program”
Your python file would have to write something like this: f.write('+prog template') f.write(f'let#from_py {sofi}') # original f.write('prt#from_py') f.write('end')
You can have several programs in an applied file.
Check out the csm examples in your installation folder and how sofistik applies the *_csm.dat files
The cmd way:
Put whatever you want to run in separate teddy files that calculate towards the same cdb (with #define project)
Run the files via wps/sps from a batch script consecutively (each file starts its own calculation process)
For a simple “include at runtime” go with apply.
For more complicated processes the batch script approach lets you do almost anything.
EDIT:
I now realise that doing this actually doesn’t change the fact the sofistik still scans through the file for #include, etc. so it shouldn’t actually work as it should still try to find the #include first?
But then… why does it work?
Original post
Ah that does make sense, thank you very much for that explanation, I’ll keep that in mind for future projects.
For the +apply method, I do, as you also point out, see possible issues in larger projects.
Specifically, I’ve previously used python to generate large files with if functions as a workaround for sofistiks missing matrix functionality. As such I have I have made slight changes to the code you provided where I generate a +prog template with python containing a #Define. Thereby I can include the definition after generation, and force sofistik to read it line by line, while I’m still able to include it when I actually need it.
Please find both the main file and the python generated file below: main.dat:
+prog template urs:1 $ from_sofi
<TEXT,FILE=from_sofi.dat>
10
</TEXT>
END
+sys python test.py
+apply from_py.dat
+prog template urs:2 $ back to sofi
loop#row 2
loop#i 2
#include test
prt#from_py(#i)
endloop
endloop
END
from_py.dat:
+prog template $ python generated files
#define test
if #row == 0
sto#from_py(0) 50.0
sto#from_py(1) 100.0
else #row == 1
sto#from_py(0) 200.0
sto#from_py(1) 400.0
endif
#ENDDEF
END
Well sometimes things in sofistik works even when they shouldn’t.
See this as a bug or a unintended feature.
It could also be reading an old version of test. You should check that.
I try to make sure that everything that is run time generated is within the +apply file.
You never know when developers discover “unintended features” and eliminate them.