-2

I am trying create child scripts from one parent script where a few parameters are modified (48 child scripts, so automation would be preferred). My intention for this is to run different Modelica scripts as individual Slurm jobs. I would normally do this with the Modelica scripting language, but since I need to submit each script individually I will need to create multiple scripts. The pseudocode is as follows. Note: The search strings are unique

load('model.mo') # modelica file, parent script
# change the control strategy in the script 
for i in ['control_1', 'control_2', 'control_3', 'control 4']:
    # change the amount of electricity generation
    find and replace r'moduleName = "control"' with 'moduleName = control_' + str(i)
    for j in [3, 7]:
        find and replace '.CombiTimeTable solar_data(columns = {2}' with '.CombiTimeTable solar_data(columns = {' + str(j) + '}'
    # change the battery size
        for k in [2000000000, 4000000000, 6000000000]:            
            find and replace 'Storage.Battery BESS(EMax = 2000000000, SOC_start = 0.5, pf = 0.9)' with 'Storage.Battery BESS(EMax = ' + str(k) + ', SOC_start = 0.5, pf = 0.9)'
            for l in ['4', '8']:
               find and replace '.CombiTimeTable ev_data(columns = {2}' with '.CombiTimeTable ev_data(columns = {' + str(i) + '}'
               export('child_model_#.mo')

My goal is to change the actual text of each new script, not just the variables. I am not sure if I should use Python, Bash, or something else for this task, especially since I am modifying a non-.txt file.

5
  • What does modifying a non .txt file mean to you? If it's just about the file name extension: that's irrelevant. If the content is text, you can do a simple string replacement, provided that your search strings are unique. If they're not, you should give more details. In any case, you didn't ask a question, so what do you expect us to answer? Commented May 27, 2024 at 6:28
  • Not familiar with Modelica, but the standard solution in any language would be to parametrize the script and pass the parameters on the command line somehow. Commented May 27, 2024 at 7:13
  • @Manfred yes the search strings are unique, but I am not sure how to do a simple string replacement. My goal is automate a find and replace. Commented May 27, 2024 at 17:12
  • @tripleee I agree, but I cannot really modify the script since I need run each .mo file individually since I will be running a slurm job. Commented May 27, 2024 at 17:13
  • None of this seems particularly challenging, but the inner loop will overwrite the results of the outer loop on every iteration. Or do you mean # in the export file name should be a combination of the i, j, k, and l values? Commented May 27, 2024 at 20:01

1 Answer 1

1

If I am able to correctly guess what you want, your pseudocode was actually pretty close to valid Python code.

I am assuming model.mo is actually a text file, and that "non-.txt" in your question just refers to the .mo extension. Python (or Slurm, or presumably Modelica) doesn't care what you call your files; the extension is purely a human convention on sane platforms. (I am consciously wording this so as to exclude Windows.)

with open('model.mo') as modelica:
    script = modelica.read()
# did you really want a space instead of an underscore in 'control 4'?
for i in ['control_1', 'control_2', 'control_3', 'control 4']:
    ivar = script.replace(
        'moduleName = "control"',
        # guessing you wanted to keep the double quotes around the name here
        # this generates "control_control_1"; maybe you meant to omit the control_ prefix?
        f'moduleName = "control_{i}"')
    for j in [3, 7]:
        jvar = ivar.replace(
            '.CombiTimeTable solar_data(columns = {2}',
            f'.CombiTimeTable solar_data(columns = {{{j}}}')
        for k in [2000000000, 4000000000, 6000000000]:
            kvar = jvar.replace(
                'Storage.Battery BESS(EMax = 2000000000, SOC_start = 0.5, pf = 0.9)',
                f'Storage.Battery BESS(EMax = {k}, SOC_start = 0.5, pf = 0.9)')
            for l in ['4', '8']:
                lvar = kvar.replace(
                    '.CombiTimeTable ev_data(columns = {2}',
                    # guessing you meant to keep the braces, and you wanted l, not i?
                    f'.CombiTimeTable ev_data(columns = {{{l}}}')
                # Guessing as to what exactly the file name should be
                with open(f'child_model_{i}_{j}_{k}_{l}.mo', 'w') as child:
                    child.write(lvar)

In particular, perhaps notice how f'strings' allow you to interpolate variables with {variable}. The notation {{ inserts a literal opening brace, and }} a single literal closing brace. There are many options for how to format interpolated variables and expressions; for example {j:02} would produce the value of j with at least two digits and padding with leading zeros if necessary.

As such, your + str(j) + attempts would work fine as well; it's just a lot more clunky.

I added comments where I had to guess what you really wanted.

Nominally, using round parentheses instead of square brackets around the enumerations would be very slightly more efficient, but that's hardly a major concern here. My main concern would be whether the names of the generated files are what you wanted. If you want to abbreviate, perhaps use a dictionary, like

abbrev_k = {
    "2B": 2_000_000_000,
    "4B": 4_000_000_000,
    "6B": 6_000_000_000
}
...
        for k in abbrev_k.keys():
            kvar = jvar.replace(
                'Storage.Battery BESS(EMax = 2000000000, SOC_start = 0.5, pf = 0.9)',
                f'Storage.Battery BESS(EMax = {abbrev_k[k]}, SOC_start = 0.5, pf = 0.9)'

to use the abbreviation 2B in the file name, but have it translated to the numeric value 2,000,000,000 in the generated file.

Demo: https://ideone.com/cP7KRx

You'll notice that we use script to hold the contents of the original script, and then in the first substitution, we create a copy of it in ivar with the control string modified, then continue to create new variables jvar, kvar, lvar with a modified copy throughout the rest of the script.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.