Message Boards Message Boards

Create a package for a function in .wl format?

Posted 9 years ago

Hello, I have been developing a CDF file (a toy problem) to teach me how to use CDF file for more serious codes deployment. I got many help in here and I am thankful for that. Before Mathematica I was using MATLAB extensively and I feel like MATLAB is much more user friendly than Mathematica, specially in developing subroutines (packages for Mathematica) . Here is the code without package but with a function and it works fine.

Manipulate[
 DynamicModule[{f = Sin[x], xR = 1, xL = 0, 
   Res = 0.4596976941318603`16}, 
  Column[{Style["1D Definite Integral Calculator", "Function"] , 
    Row[{"Lower Limit ", InputField[Dynamic[xL], Number]}, Spacer[5]],
     Row[{"Upper Limit ", InputField[Dynamic[xR], Number]}, 
     Spacer[5]], 
    Row[{"Function  ", InputField[Dynamic[f]]}, Spacer[20]], 
    Button[Style["Calculate", Green, Bold], 
     Dynamic[Res = WD1Int[f, xR, xL, np, nw];]], 
    Row[{"Result", InputField[Dynamic[Res], Enabled -> False]}, 
     Spacer[51]], 
    Row[{"Plot the Function ", Checkbox[Dynamic[fp], {False, True}]}],
     If[fp == True, 
     InputField[
      Dynamic[Plot[f, {x, xL, xR}, Dynamic[PlotLabel -> f], 
        ImageSize -> Full]], FieldSize -> {30, 15}]], 
    Button[Mouseover[Style["http://www.wolfram.com", "Hyperlink"], 
      Style["http://www.wolfram.com", "HyperlinkActive"]], 
     NotebookLocate[{URL["http://www.wolfram.com"], None}], 
     Appearance -> None]}]], {{np, 16, "NumberFormat"}, 
  ControlPlacement -> Bottom}, {{nw, 16, "WorkingPrecision"}, 
  ControlPlacement -> Bottom}, Initialization :>
  (WD1Int[f_, xR_, xL_, np_, nw_] := 
     Module[{xLcheck, xRcheck}, xLcheck = NumberQ[xL];
      xRcheck = NumberQ[xR];
      If[xLcheck == True && xRcheck == True, 
       WResultTF = 
        SetPrecision[
         NIntegrate[f, {x, xL, xR}, 
          WorkingPrecision -> Re[IntegerPart[nw]]], 
         Re[IntegerPart[np]]], 
       "Enter numeric inputs for Lower and Upper Limits"]];)]

I would like to use package for my function so I can Encode it (I am using Enterprise CDF). During this process I have been facing several problems. Here is how create the package and updated the function. I use .wl because I have MATLAB in my computer too.

Manipulate[
 DynamicModule[{f = Sin[x], xR = 1, xL = 0, 
   Res = 0.4596976941318603`16}, 
  Column[{Style["1D Definite Integral Calculator", "Function"] , 
    Row[{"Lower Limit ", InputField[Dynamic[xL], Number]}, Spacer[5]],
     Row[{"Upper Limit ", InputField[Dynamic[xR], Number]}, 
     Spacer[5]], 
    Row[{"Function  ", InputField[Dynamic[f]]}, Spacer[20]], 
    Button[Style["Calculate", Green, Bold], 
     Dynamic[Res = TFPackageSourceCode`WD1Int[f, xR, xL, np, nw];]], 
    Row[{"Result", InputField[Dynamic[Res], Enabled -> False]}, 
     Spacer[51]], 
    Row[{"Plot the Function ", Checkbox[Dynamic[fp], {False, True}]}],
     If[fp == True, 
     InputField[
      Dynamic[Plot[f, {x, xL, xR}, Dynamic[PlotLabel -> f], 
        ImageSize -> Full]], FieldSize -> {30, 15}]], 
    Button[Mouseover[Style["http://www.wolfram.com", "Hyperlink"], 
      Style["http://www.wolfram.com", "HyperlinkActive"]], 
     NotebookLocate[{URL["http://www.wolfram.com"], None}], 
     Appearance -> None]}]], {{np, 16, "NumberFormat"}, 
  ControlPlacement -> Bottom}, {{nw, 16, "WorkingPrecision"}, 
  ControlPlacement -> Bottom}, Initialization :>
  (Needs["TFPackageSourceCode.wl"];)]

and the package TFPackageSourceCode.wl follows like this

   BeginPackage["TFPackageSourceCode`"];
WD1Int::usage="";
Begin["`Private`"];
    WD1Int[f_,xR_,xL_,np_,nw_]:=Module[{xLcheck,xRcheck},xLcheck=NumberQ[xL];
    xRcheck=NumberQ[xR];
    If[xLcheck==True&&xRcheck==True,WResultTF=SetPrecision[NIntegrate[f,{x,xL,xR},WorkingPrecision->Re[IntegerPart[nw]]],Re[IntegerPart[np]]],"Enter numeric inputs for Lower and Upper Limits"]];
    SetAttributes[WD1Int,{ReadProtected,Protected,Locked}];
    End[];
    EndPackage[];

Both the package and the main file is in the same folder and it is in the $Path. (I think only having the package in the $Path should be enough). But the code does not work without any error.

enter image description here

I also tried to use this line for initialization

(Get[FileNameJoin[{NotebookDirectory[EvaluationNotebook[]],
"TF1DINTPackageSourceCode.wl"}]];)]

They both don't work and I don't know why. To be honest, I have been creating many files to improve the code in every step and I have some files working with packages some are not. That is why I said ANNOYING in the tittle. I deleted all my files and started to work on from zero so I can clearly create working code in a single file which later on I can mimic.

My other major problem is shadowing and private and global variable problem. Some times my variables are red and I get an warning that there are more than one variable named same (not in the same nb) and one of the definition can be shadowed and it can be the current definition. That means if I have 2 versions of the same code (maybe all the variable are same just different coding) Mathematica will be seeing the second function/package too. For me it is really inconvenient and I dont see the advantage of having just Kernel memory. I get this error even my package is "Private" . So what does Private do for me?

enter image description here

I used ClearAll at the beginning of my code but I assume it is not same effect as it is in MATLAB. I don't understand why each nb can't be self contained and variable stay in there.

http://community.wolfram.com/groups/-/m/t/850076

Here I asked the question for that and Kuba is trying to help me. I know that this should not be this hard.

Thank you for the replies.

ps: I could not upload .wl file because the forum did not allow that extension.

Attachments:
POSTED BY: Erdem Uguz
4 Replies

Hello Erdem, I also deploy to EnterpriseCDF and I use a package to contain most of the non GUI code. I do it like this:

Needs["MyPackage"]; myGUI=Manipulate[(...),Initialization :> (Needs["MyPackage"]), SaveDefinitions -> True];

To avoid issues related to SaveDefinitions, I always quit the kernel, evaluate the initialization cells (including code above) and then CDFDeploy[] it.

For more info I recommend you this excellent presentation "User Interface Programming" by Faisal Whelpley and Lou D`Andria: http://library.wolfram.com/infocenter/Conferences/7977/

Regards,

Gustavo Delfino

POSTED BY: Gustavo Delfino
Posted 9 years ago

Thank you for the link. I will for sure look into it. I think my main problem is with the private command in the package. When I remove

WD1Int::usage=""; Begin["Private"];*)

part from the package and run the Quit command (as you suggested) before running the main file. I don't have a problem. That raises the question what is the problem with making package Private. Why do you include Needs["TFPackageSourceCode.wl"] at the beginning and again in the initialization part ?

POSTED BY: Erdem Uguz
Posted 9 years ago

For whatever it's worth, I couldn't get the first example to work using Mathematica 10.4.1 (Windows 10) until I moved the function WD1Int outside of the Manipulate.

But in any event, isn't the problem that CDF does not allow text input? Numerical input, yes. Text input no. So such things work in Mathematica but not in the CDF Reader. You could replace the InputField with a PopupMenu. And using SaveDefinitions -> True would also fix the inclusion of functions outside of the Manipulate.

POSTED BY: Jim Baldwin
Posted 9 years ago

I just copy and paste the first example (to check if I didn't transfer correctly while posting) but it is working fine. I used enterprise CDF with Enterprise CDF you can create string inputs.

when you move the function outside the Manipulate how are you going to "Manipulate" . Here a version of the code without Manipulate.

DynamicModule[{f = Sin[z], zR = 1, zL = 0, Res = 0.45969},
 Column[{Style["1D Definite Integral Calculator", "Function"] , 
   Row[{"Lower Limit ", InputField[Dynamic[zL], Number]}, Spacer[5]], 
   Row[{"Upper Limit ", InputField[Dynamic[zR], Number]}, Spacer[5]], 
   Row[{"Function  ", InputField[Dynamic[f]]}, Spacer[20]], 
   Button[Style["Calculate", Green, Bold], 
    Dynamic[Res = DTL[f, zR, zL, 16, 16];]], 
   Row[{"Result", InputField[Dynamic[Res], Enabled -> False]}, 
    Spacer[51]],
   }],
 Initialization :> (DTL[f_, zR_, zL_, np_, nw_] := 
    Module[{xLcheck, xRcheck}, xLcheck = NumberQ[zL];
     xRcheck = NumberQ[zR];
     If[xLcheck == True && xRcheck == True, 
      ResultTF1 = 
       SetPrecision[
        NIntegrate[f, {z, zL, zR}, 
         WorkingPrecision -> Re[IntegerPart[nw]]], 
        Re[IntegerPart[np]]], 
      "Enter numeric inputs for Lower and Upper Limits"]])]

and to be honest I am not sure what is the difference between Manipulate and DynamicModule because you can create dynamic input fields just with manipulate too.

POSTED BY: Erdem Uguz
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract