zenterix

310 Reputation

4 Badges

3 years, 97 days

MaplePrimes Activity


These are questions asked by zenterix

Let's say I have a file test.mpl file in the path ~/maple/Packages/MyPackage/test.mpl.

From the code in this file, I wish to save something to a file in the directory at the relative path ./Animations, which has absolute path ~/maple/Packages/MyPackage/Animations.

Now, on my machine, because I know the path to this directory I can easily save using the absolute path. 

What if I send this directory MyPackage (which is essentially a package) to someone else. Maybe they keep it in a different location such as ~/projects/maple-projects/MyPackage.

I would like that this person be able to run test.mpl and it will save the aforementioned something to a file in the relative location ./Animations, which on their machine is the absolute path ~/projects/maple-projects/MyPackage/Animations.

I am stuck on how to accomplish this.

I found out that if I am in a worksheet that is in the directory MyPackage then I can use interface(worksheetdir) to find out the path to the worksheet, so if everything were run from a worksheet contained in the MyPackages directory then I could use a relative path to the Animations directory. 

Problem is, the normal usage of test.mpl is to just create some new worksheet and read the file and use it. But a new worksheet like this is located in the home directory by default.

Let's say I am solving a system of differential equation numerically with dsolve. 

In psolve, I use the option output = Array(...), and I assign the result of the call to a variable p. Given my problem such calls can take a few minutes to run.

Later I use odeplot and pass in this variable p. In this workflow I am doing all this in a single worksheet.

Now, I'd like to run dsolve multiple times and save the results of calls to files so that I can plot them later (what I am actually doing is running some code using the Grid package, and I would like each parallel process to save the plot data).

It would actually be great if I could run this code as a batch file. I am not sure how to do this yet (I read about some command line mode that would be best for this). 

So my questions are

- What is the recommended way to save data to files for loading later on?

- Does the answer the the above question work in command-line mode?

I am trying to do something which I am almost able to do but I have what seems like a final roadblock.

My goal is to be able to call procedures that dynamically update the maple initialization file (init on a Mac, located at ~/Library/Frameworks/Maple.framework/Versions/2022/lib/init).

Let's say this file starts empty.

I want to be able to use a procedure addPackageDirectoryToLibname that will remove all the contents of init and replace it with a newly constructed string. 

The newly constructed string will be libname: and then the previous libname string (which is just libname while the procedure is executing), prepended with an argument to the procedure, packageDir.

So, something like libname := MyNewDir, libname:

I also want to have a procedure removeEntryFromLibname that removes the entry in libname at the argument index.

Now I can already do all of this EXCEPT I can't remove the contents of the file init. Therefore, I am simply adding ever longer strings to init. I don't want to delete the file and recreate it, though I could do this. How do I wipe the contents of init clean programatically?

A few observations

- I had a working version of addPackageDirectoryToLibname but I realized that it was too limited (for the record, it was just adding a new line to the init file each time. The new line was something like libname := MyNewDirectory, libname:.

There is a problem that for my personal use is minor (but if this were for more widespread use I would want to fix it): if addPackageDirectoryToLibname works, you can't call it twice in a row without a restart:, because it depends on the current value of libname. After adding something to libname if you add something else, this something else will be added to the old libname, not the libname that was updated.

If you'd like to see the code I have so far, you can see it in this Github repository.

MyPackageTools := module()
    option package;

    export addPackageDirectoryToLibname, savePackageToMla;

    addPackageDirectoryToLibname := proc(packageDir)

        local mapleInitFile, newLibname:

        mapleInitFile := "/Library/Frameworks/Maple.framework/Versions/2022/lib/init":

        try 
            FileTools:-Text:-Open(mapleInitFile, 'append'):
        catch:
            return "Failed to open file":
        end:

        try
            newLibname := cat("libname := \"", packageDir, "\", libname:" ):
            FileTools:-Text:-WriteLine(mapleInitFile, newLibname):
        catch:
            FileTools:-Text:-Close(mapleInitFile):  
            return "Failed to write to file.": 
        end: 

        try
            FileTools:-Text:-Close(mapleInitFile):   
            return "Added to libname successfully. Restart worksheet for changes to come into effect.":
        catch: 
            return "Failed to close file":
        end:
    end:

    savePackageToMla := proc(mlaPath, mplPath, packageName)

        read(mplPath);

        LibraryTools:-Save(packageName, mlaPath);

    end:
end:

I'd like to automate my workflow a bit. I having a hard time making savePackageToMla work. The commands inside it are the ones I would run in a Maple worksheet to save a package to an .mla file.

The error I get when I try to use this is

Error, (in LibraryTools:-Save) 1st variable is not a name or equation |/Users/marcusegues/maple/Packages/MyPackageTools/MyPackageTools.mpl:38|

Note that the goal is to pass in an mla path and an mpl path. The mpl file is read. The package that is read is the same as the argument packageName. 

I invoke this procedure with something like

savePackageToMla(mlaPath, mplPath, 'MyPackage')

where 

mplPath := '/somePath/MyPackage.mpl';
mlaPath := 'somePath/MyPackage.mla';

and MyPackage.mpl contains something like

MyPackage := module()
  option package;
  (...)
end;

My question is based on this worksheet: uneval.mw

Consider the following procedure

myTest1 := proc()
     local s, gen;
     gen := proc()
          return 5;
     end

     s := seq(['gen()', 'gen()', 'gen()']);
     print(s);
     return s;

end;

If I call this procedure, myTest1(), the result is gen(),gen(),gen() printed out and then also returned from the procedure.

If I change local s to global s, the result changes to 5,5,5. That is, the sequence 5,5,5 is both printed and returned.

Why?

In the attached worksheet I have both cases that you can test.

First 9 10 11 12 13 14 15 Page 11 of 15