Skip to main content

notebooks - CDF, Player, PlayerPro, or something else?


I have a notebook, which contains a dozen or so custom functions all leading to the production of a simple static report, something like this:


enter image description here



I want to distribute this to a single user who will run (or execute) it a couple of times a day. I can get them a copy of Mathematica, but that seems overkill for this. They want something very simple.


The notebook as it stands gets computable data via FinancialData[] for a single instrument and has hard code for all other required inputs.


It requires only a single interaction with the user: pushing the "Run report" button (or some equivalent means of evaluating the code).


The code for the actual report uses some proprietary functions, which I want to protect and hide from the user.


Ideally, the end user should only see the latest report and the "Run report" button.


So, can anyone suggest the best solution for distributing such a computable but otherwise non-interactive report? It doesn't have any need for a Manipulate[] as I see it, so at first thought CDF seems the wrong fit.


Should I go with Player or Player Pro and simply hide the cells with functions? Does CDF make more sense?


CDF, Player Pro, Notebook comparison


I think you can see that I want simple, robust, and secure for this. Just a simple stand alone app.


Thx.



P.S., We don't seem to have a tag for "player".



Answer



I think this sounds like an ideal use case for a CDF document and the free CDF player to "play" it. It's not necessary that the interactivity within a CDF document is more complicated than reacting to a button press :-). You will find other answers with examples that show that it is also not necessary to use a Manipulate, you can very well deploy a custom gui based on e.g. DynamicModule as a CDF document as well. It's easy enough to create a Manipulate with the desired functionality, though:


Manipulate[
result = runit[];
Dynamic[result],
{result, None},
Button["Run", result = runit[];, Method -> "Queued"],
Initialization :> (runit[] :=
DateListPlot[{#1, #2 + RandomReal[]} & @@@

FinancialData["GE", "Jan. 1, 2010"]]),
SynchronousInitialization -> False
]

The only drawback with using the free CDF player for your use case that I see is that it's not possible to securely hide your code (except for whatever you write yourself to hide it, which might be more or less hard to uncover). There are means to hide it in such a way that it will need rather good knowledge and some criminal effort to uncover it, but usually these approaches turn out to be surprisingly simple to hack if you let the right people try.


If your end user gets a PlayerPro license you can in principle deploy your program as an encrypted package (which the PlayerPro can read but not the CDF-Player). You can then also create such encrypted packages that only will run on specific machines (checking $MachineId) or with specific licenses (checking $LicenseID). That is a relative straightforward way to ensure that the code won't be passed away.


There are rumours that this encryption is also not terrible difficult to hack. Doing so would actually need somewhat more criminal effort than hacking an "obfuscated" CDF-Document but I absolutely wouldn't exclude it can be done. With PlayerPro you can also load a .mx package which are considered somewhat safer than an encryped package but honestly it's not clear to me whether that's really true (that they are safer). .mx files are also platform dependent, so depending on how many customers and platforms you need to support that might add some complexity. And as they are, AFAIK, no "cross platform save" possibilities the only way to create the .mx files for a set of platforms is to have a Mathematica installed and licensed one each of those you want to support (possibly in 32 and 64 bit variants).


My personal opinion is that code is "protected" well enough if the effort to hack it is higher than the effort to rewrite it. If you ask the right persons it often turns out that hurdles for both alternatives are a lot lower than one would have guessed. On the other hand I would consider it to be an overestimation of my own code that those "right persons" would try or be engaged to hack it. So my suggestion would be to use a CDF-document with code coming e.g. from a compressed expression and include a license information which makes clear what the user is allowed to do and what not. I found that this will, at least within a professional environment, almost always have the desired effect.


Comments

Popular posts from this blog

mathematical optimization - Minimizing using indices, error: Part::pkspec1: The expression cannot be used as a part specification

I want to use Minimize where the variables to minimize are indices pointing into an array. Here a MWE that hopefully shows what my problem is. vars = u@# & /@ Range[3]; cons = Flatten@ { Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; Minimize[{Total@((vec1[[#]] - vec2[[u[#]]])^2 & /@ Range[1, 3]), cons}, vars, Integers] The error I get: Part::pkspec1: The expression u[1] cannot be used as a part specification. >> Answer Ok, it seems that one can get around Mathematica trying to evaluate vec2[[u[1]]] too early by using the function Indexed[vec2,u[1]] . The working MWE would then look like the following: vars = u@# & /@ Range[3]; cons = Flatten@{ Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; NMinimize[ {Total@((vec1[[#]] - Indexed[vec2, u[#]])^2 & /@ R...

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

What is and isn't a valid variable specification for Manipulate?

I have an expression whose terms have arguments (representing subscripts), like this: myExpr = A[0] + V[1,T] I would like to put it inside a Manipulate to see its value as I move around the parameters. (The goal is eventually to plot it wrt one of the variables inside.) However, Mathematica complains when I set V[1,T] as a manipulated variable: Manipulate[Evaluate[myExpr], {A[0], 0, 1}, {V[1, T], 0, 1}] (*Manipulate::vsform: Manipulate argument {V[1,T],0,1} does not have the correct form for a variable specification. >> *) As a workaround, if I get rid of the symbol T inside the argument, it works fine: Manipulate[ Evaluate[myExpr /. T -> 15], {A[0], 0, 1}, {V[1, 15], 0, 1}] Why this behavior? Can anyone point me to the documentation that says what counts as a valid variable? And is there a way to get Manpiulate to accept an expression with a symbolic argument as a variable? Investigations I've done so far: I tried using variableQ from this answer , but it says V[1...