Re: Strategies to re-engineer someone else's notebook?

*To*: mathgroup at smc.vnet.net*Subject*: [mg116757] Re: Strategies to re-engineer someone else's notebook?*From*: "andre.robin3" <andre.robin3 at wanadoo.fr>*Date*: Sat, 26 Feb 2011 06:07:50 -0500 (EST)*References*: <ik5fbl$sl6$1@smc.vnet.net>

"W. Craig Carter" <ccarter at mit.edu> a écrit dans le message de news: ik5fbl$sl6$1 at smc.vnet.net... > Mathgroup, > This is perhaps an odd but practical query, and I am guessing that some > of you have tackled similar. Sorry for the lengthy question below. > > What is a plausible strategy to "improve" a working notebook, where the > notebook is written in the way many beginners-to-Mathematica write > notebooks? > > The user that I am helping runs her notebook by changing one variable, > evaluating the notebook, killing the kernel, changing another variable, > evaluating the notebook.... > > For a concrete and artificial (hopefully amusing) example that is > representative of about 1000 lines of code that probably started its > life as a giant spreadsheet: the target notebook to be fixed might look > like this > > (**********) > hamburgerMass = proteins + veggies + starch; > hamburgerCalories = proteins proteinCalorieDensity + veggies > veggieCalorieDensity + starch starchCalorieDensity; > > meat = 12; > lettuce = 8; > cheese = 13; > pickles = 1; > bun = 0.5; > > proteins = If[CheeseBurger,cheese + meat,meat]; > veggies = lettuce + pickles; > starch = bun; > > hamburgerCosts = meat meatCosts + veggies veggieCosts + starch starchCosts > > (*etc etc. Output from expressions at line 1000 become very long*) > (******************) > Sometimes the user wishes to know only the number of calories, sometimes a > pie chart of calorie contributions, and sometimes things like: > = > ParametricPlot[{hamburgerMass/.meat->x,hamburgerCalories/.meat->x},{x,0,1}] > (*with all other variables assigned*). > > > My current strategy is to leave out any assignments, evaluate the > notebook from a fresh kernel, and then find the dependencies of > "derived" expressions using a function like this: > vars[expr_] := Union[Cases[expr, a_ /; (! NumberQ[a] && AtomQ[a]), > Infinity]] > which gives all the symbols on which expr depends, > and then use these independent variables to construct functions by > cutting and pasting. Tedious, but a path towards doing something useful > with Manipulate. > > Another approach may be to make everything a delayed assignment; another > would be to make everything Dynamic. Here is another approach which is probably better : 1) make a list of delayed Rules corresponding to all the variables assignments (can be done programmaticaly, see (*) ) : ruleList00={ HoldPattern[hamburgerMass] :> proteins + veggies + starch, HoldPattern[hamburgerCalories] :> proteins proteinCalorieDensity + veggies veggieCalorieDensity + starch starchCalorieDensity, HoldPattern[meat] :> 12, ... HoldPattern[hamburgerCosts] :> meat meatCosts + veggies veggieCosts + starch starchCosts ...} 2) Save ruleList00 3) Quit Kernel. (This remove all definitions) 4) Recall ruleList00 3) then "manually" control the replacements for each query of the user : (hamburgerMass /. {meat->x, anythingYouWantToKeepLitteral -> y... }) //.ruleList00 This is very powerfull. For example if the variable CheeseBurger is not defined, it will appear so, in the litteral form "CheeseBurger" in the result. You can also add rules as CheeseBurger :> "toBeDefineLater". In fact, this is exactly the way Mathematica works, but here you have more control of the ordering of replacements. (*) to programmaticaly make the list rulesList00 : - in the cell containing the definitions, remplace all the = (Set) by := (SetDelayed) - evaluate the cell - evaluate : rulesList00 = Flatten[With[{unevaluatedSymbol = ToExpression[#, InputForm, Unevaluated]}, OwnValues[unevaluatedSymbol ]] & /@ Names["Global`*"]] > > > Any ideas how I might do this with less tedium and error? Also, if the > naive-notebook generator wishes to change a single line, I'd like to be > able to re-engineer her notebook without duplicate labor. > Thanks, Craig