Showing posts with label Mathematica. Show all posts
Showing posts with label Mathematica. Show all posts

2010-08-24

Form style dialogs

When you are creating your user interfaces you often want to produce a pop up form.  The code below is not perfect in that when you close the form it asks you if you want to save but it is workable:

ReportUnderConstruction[] := NotebookPut[Notebook[{
    Cell["Report under construction", "Text"]
    }]]

testForm[] := DynamicModule[{},
  Column[{
    TextCell["Form", "Section"],
    Text@TextCell["Reconciliation 2010-08-24", "Subsection"],
    Text@TextCell["Sample controls to illustrate a dialog box.",
      "Text", FontColor -> Darker@Blue],
    Spacer[10],
    Button[Style["Show Report", FontFamily -> "Helvetica"],
     ReportUnderConstruction[]],
    Spacer[10],
    Button[Style["Reset Report", FontFamily -> "Helvetica"],
     ReportUnderConstruction[]],
    Spacer[10]
    }]]

Button["Form", nb = NotebookPut[Notebook[{
     Cell["testForm[]", "Input", CellOpen -> False]
     }]];
SelectionMove[nb, Next, Cell];
SelectionEvaluateCreateCell[nb]]

This looks like this:

image

When you click on the button you get the pop up form:

image

Those buttons then produce a very simple report:

image

2010-07-23

Mathematica Initialization cell

I have been trying to develop little Mathematica applications.  A misconception I have had is that an initialization cell  will run when you open the notebook.  However I don’t think it runs until you either execute another cell when you are then asked to run all initialization cells or Evaluate Initialization Cells from a menu.  However with Player Pro I don’t think it is posible to start an application without clicking once.

Dynamic cells I don’t think help as you still get a “Dynamic Content Warning” dialog box which is offputting to naive users.

I am looking to do a double bootstrap deployment, the first bootstrap gives you a very simple loader notebook which you can deploy on Mathematica Player Pro.  You open it eg from File Explorer click the button and you have your application ready to go.  This is a very simple application.

image

Then you can add other options eg deploying your files to where you need them etc.  I plan to cover later a more complicated example with code in modules and a good user interface using tabbed windows.  Then you need to compress the packages which can all be done with Mathematica. (The first time I did this I made the mistake of unbundling the definitions of report and myProgram so that they didn’t work in the loader.  When I clicked the button on the loader they hadn’t been defined so nothing happened.*)

To save anybody the effort of typing I have the text of the above here s:

myLoader = Notebook[{
    Cell[Button["My Loader",
      NotebookPut[Notebook[{Cell["BootStrap Application"]}]]], "Text"],
    Cell[BoxData[ButtonBox["\<\"Run the Program\"\>",
       Appearance -> Automatic, ButtonFunction :>
        ((*These definitions need to be executed by the click of the \
button to make them available later*)
         report = Notebook[{Cell["Simplest report", "Text"]}];
         myProgram = Notebook[{
            Cell[Button["My Program",
              NotebookPut[Notebook[{Cell["BootStrap Application"]}]]],
              "Text"],
            Cell[BoxData[ButtonBox["\<\"Run the Report\"\>",
               Appearance -> Automatic, ButtonFunction :>
                (
                 NotebookPut[report]
                 ), Evaluator -> Automatic, Method -> "Preemptive"]],
             "Output"]
            }];
         NotebookPut[myProgram];
         NotebookClose[] (*Loader's job is done and it closes to
         prevent any errors corrupting it*)
         ), Evaluator -> Automatic, Method -> "Preemptive"]], "Output"]
    }];

Button["Create Loader",
nb = NotebookPut[myLoader];
NotebookSave[nb, NotebookDirectory[] <> "Loader.nb"]
]

2010-03-25

Mathematica Run and spaces

On Windows I have been trying to interface to another program.  This is due to the PlayerPro not supporting the .NET interface so you can’t do COM object manipulation.  So I am putting any of that code into an exe built by  Autoit and then want Mathematica to call it with variable parameters.

However  I have had real trouble using the Run[] command to run a progam which has a command and a parameter with a filename with spaces in it.

Run[“\”F:\\A dir\\test.exe\" “\”F:\\A dir\\data\"”]

so my work around is to put the command in a batch file Run.bat and then run:

Run[“\”F:\\A dir\\run.bat\"”]

Which is irritating but works.

I used the following to build the command file:

batchRun[workingDir_, command_] := Module[{fn, str},
  fn = workingDir <> "Run.bat";
  If[FileExistsQ[fn], DeleteFile[fn]];
  str = OpenWrite[fn];
  WriteString[str, command];
  Close[str];
  Run["\"" <> fn <> "\""]
  ]

2010-03-23

Mathematica Player Pro deployment process

Starting with a working notebook and assuming that you are working in workbench.  The aim is then to first convert this into very simple notebook with all the gui code in a gui package.  Then to combine all these elements into an installable exe file using InnoSetup for deployment on a machine with PlayerPro installed or just copy them across to your destination.

1) Convert the Gui cells to initialisation cells.  This then saves the code to .m package.

2) Supposing you want to keep the template separate then Rename the saved notebook to something else eg _template.  Rename the saved .m file as smethingGUI.m and the template.

3)Edit somethingGUI.m into a package file with a single function runGUI[]. 

a) Whereas before you might have explicit dependencies in the code eg Needs{moduleX`]  this can now be moved into the begin package dependency list:

BeginPackage["somethng`",  {"moduleX`"}]

b) Any references to global variables will now need to be prefixed with Global` now that they are embedded in a private part of the package.

4) Create a new notebook with the single cell and interface

If[Fold[Or, False,
   StringMatchQ[$Path, ___ ~~ "MathematicaPlayerPro" ~~ ___]],
  Needs[# <> "`", NotebookDirectory[] <> # <> ".mx"] &,
  Needs[# <> "`"] &] /@ {"moduleX”, 
  "somethingGUI"}; somethingGUI`runGUI[]

5) Open this notebook with the Mathematica front end  and run it.  It should work, eg display front end and then allow you to interact with the front end.

6) Edit the Gui code for the button and modify  like this

Dynamic@Button[Style["Run report",FontFamily->"Helvetica"],
      (

If[Fold[Or, False,
   StringMatchQ[$Path, ___ ~~ "MathematicaPlayerPro" ~~ ___]],
  Needs[# <> "`", NotebookDirectory[] <> # <> ".mx"] &,
  Needs[# <> "`"] &] /@ {"moduleX”, 
  "somethingGUI"};

        something`createReport[thisDate];
      ),Enabled->fileExists
    ]

(The fileExists is a dynamic variable that depends on a file test depdning on what the user puts in.  If the file doesn’t exsit the buton is not enabled) (This is a bit of kludge but seems to work.  When you save a result it sees to save partial but not all linked files so then using a Needs in the button procedure loads the path but not quite quickly enough so you need to use complete references.  you need to open the file in the front end and execute the code then make code option not open and then save the notebook.  You now get a blank notebook that opens and you can press buttons. on it.

7)  Build a build and deploy module that actually compresses the files and then deploys them to the test machine.

8) When it runs I still have the run dynamic content and run the initialistation bxes to click. but then it does start up

The next stage is to put this all together as a set of sample files.

2010-03-08

Mathematica testing notebook reports

I am just coming to grips with creating notebooks (reports) in the kernel and for testing the report.  When testing with MUnit there is no front end so it seems that all the Notebook manipulation commands such as:

    nb = CreateDocument[]

    nb = NotebookPut[]

don’t work.  So my work around is to test my own notebook.  This can be turned into an actual workbook easily on a FrontEnd eg:

In[3]:= nb = Notebook[{}]

Out[3]= Notebook[{}]

In[6]:= AppendNotebook[nb_, expr_] :=
Notebook[Append[nb[[1]], expr]]; nb =
AppendNotebook[nb, Cell["Hello", "Subsection"]]

Out[6]= Notebook[{Cell["Hello", "Subsection"]}]

In[8]:= NotebookPut[nb]

Then you can add a grid box – I have adapted a version here which produces a box even if all the tables are not quite the right length as I would rather have a grid when the data is wonky than not:

writeNotebookGrid[nb_, body_, headerList_] :=
Module[{headings, itemsBody, cols, useBody, result},
  result = AppendNotebook[nb, Cell["Table", "Subsection"]];
  If[Depth[body] < 3, useBody = {{"Body parameter not deep enough"}},
   useBody = body];
  cols = Max[Length[headerList], Length[#] & /@ useBody];
  headings =
   Map[StyleBox[#, FontFamily -> "Times", FontWeight -> "Bold",
      FontColor -> RGBColor[0.5, 0, 0.3]] &, {PadRight[headerList,
      cols, ""]}, {2}];
  itemsBody = Join[headings, PadRight[#, cols, ""] & /@ useBody];
  result =
   AppendNotebook[result,
    Cell[BoxData[
      GridBox[itemsBody, GridFrame -> True, RowLines -> True,
       ColumnLines -> True]], "Text"]];
  Return[result]
  ]

nb = writeNotebookGrid[nb, {{1, 2}, {2, 3}}, {A, B, C}]

Which gives you a little table in your report like this:

Table

Adding graphs to your plot is done like this:

ab = AppendNotebook[nb,
  Cell[BoxData[ToBoxes[Plot[Tan[x], {x, 0, \[Pi]}]], ""],
   "Text"]]; NotebookPut[ab]

The syntax is a bit fidly but will build you a notebook like this:

GraphAndTable

The great thing is that once you have these primitives you can quickly iterate through large data sets and produce detailed reports.  Especially if you spend some time on the graphs with annotations and labels.  Mathematica 7 has improved legends over Mathematica 6.

2010-03-04

Mathematica package hell

I accidentally created a circular dependency with a Package A Needs Package B which Needs Package C which needs Package A.

Having done that Package A couldn’t access Package B routines even though it correctly need them.  The full form did work eg PackageB`function[].

It is something to be careful of but there is no particular help from the compiler or workbench.  It should be possible to write a package dependency tree program quite easily.

2010-02-26

Mathematica Debugger Traps

When I first started using WorkBench 2.0 and Mathematica 7.0.1 I found the operation of the debugger flaky.  However I have identified a number of issues have helped me.

1 My problem was due to using a global connection in the module:

conn=OpenSQLConnection[…

This then prevents the debugger working.  I have now reworked my code so that I don’t use this type of connection. 

I have tested whether it is expensive to open a SQL connection on every call or if you do it just once for a group of calls.  Doing 10 simple queries took 1.7 seconds if the connection was opend and closed every time and ca 1 second if it was only opened once.  So for the generation of reports I am going to avoid the considerable work involved in doing two headers and wait until I can generate them automatically.

2 Timing.  You have to wait until the Workbench has finished loading.  This takes a number of seconds and you can easily start executing code in the opened notebook first.  If you do that the bottom right of the workbench screen will look like this:

workbenchScreenShot

The input number will be 2 rather 7 or 8 which is normal if the debugger is going to work.

3 I tried SVN addin to the workbench and that was a bad idea.  I had to uninstall and reinstall workbench to get back a working version.  I saw a post where Wolfram are working on the SVN version so I hope that comes through.

4 In the debug screen I make sure I delete other debug activities before starting a new debugging session.

5 Be good about default directories.  I tried a different directory for the module and the debugger wouldn’t breakpoint at it.  Moving it to the normal directory worked fine.

2010-02-11

Creating Monkey reports in Mathematica

What I am after is a simple way to generate reports or actually carry out work based on some user input which can be carried out in Mathematica Pro.  I have struggled with an apparent interaction between long runnng sql queries and Dynamic Module which means that the execution has been unreliable when using Dynamic modules.

I created a demo report that allows you on Mathematica to push a button, request some input and generate a report .  The issue is that does not work very nicely in Player Pro as although there is a nice button to press you need to evaluate all the code.

I have now converted this into a number of files and successfully deployed to a Mathematica Player Pro.  i have stored the files in google docs so they can be downloaded.

The demo files are:

Having got a working notebook I did the following:

  1. Converted the library code to initialisation cells.  This created an initialisation package.
  2. Converted the auto saved initialisation package “report.m” to a package by adding BeginPackage,usage info for main function, Begin[`private`],End and End package.
  3. Convert the package to an encrypted package using the helper.  You need an encrypted needs when running on Player Pro
  4. Converted the report to just a single button with no extra code.  It needs the encrypted package.  One trick is to hide the code by removing the Cell –>Cell Properties open flag.
  5. Copy the encrypted packaged and button file to another system and I have a working tool.

Good news.

2010-02-10

Options for connecting Mathematica to a MS SQL server

The following is just an example of connecting to a SQL database (actual names changed slightly)  Also showing the slightly naughty habit of using the user sa.

In[1]:= Needs["DatabaseLink`"]

In[2]:= conn =
OpenSQLConnection[JDBC["Microsoft SQL Server(jTDS)", "MyServer"],
  "Catalog" -> "MyDemo", "Username" -> "sa",
  "Password" -> "RubyPane"]

Out[2]= SQLConnection[2, "Open", "Catalog" -> "MyServer",
"TransactionIsolationLevel" -> "ReadCommitted"]

This is a useful link for getting SQLExpress to work (basically don't try the integrated security):

http://softwaresalariman.blogspot.com/2007/04/jdbc-to-sql-server-express.html

Which gets me to:

s[] := OpenSQLConnection[
  JDBC["Microsoft SQL Server(jTDS)",
   "127.0.0.1:1433/Test;user=sa;password=sa"],
  "Catalog" -> "TestTercero", "User" -> "sa", "Password" -> "sa"]