Making alias for context paths? - wolfram-mathematica

I'd like to be able to do s'Graph and c'Graph to refer to System'Graph and Combinatorica'Graph (and other functions conflicting with Combinatorica) is there a way to do this?
Following Simon's idea, the following seems to work
{Set ## {ToExpression["c" <> Last[StringSplit[#, "`"]]],
ToExpression[#]}} & /# Names["Combinatorica`*"];
{Set ## {ToExpression["s" <> Last[StringSplit[#, "`"]]],
ToExpression[#]}} & /# Names["System`*"];
Now cCompleteGraph[5] and sCompleteGraph[5] return Combinatorica and System graphs respectively
Update Jan 8th
For future reference, this is the method I ended up using to use GraphUtilities, Combinatorica and built-in graph functionality together. It resolves conflict by remapping all combinatorica functions like Graph to cGraph and changes $Post to remove GraphUtilities and Combinatorica from ContextPath on each evaluation, necessary because GraphUtilities'ToCombinatoricaGraph adds Combinatorica to $ContextPath at every call.
To summarize, execute the code below at start of each session. Combinatorica func is now cfunc, GraphUtilities func is GraphUtilities'func, and built-in func is just func
Needs["Combinatorica`"];
combNames = Names["Combinatorica`*"];
{Set ## {ToExpression["c" <> Last[StringSplit[#, "`"]]],
ToExpression[#]}} & /# Names["Combinatorica`*"];
Needs["GraphUtilities`"];
$ContextPath = DeleteCases[$ContextPath, "Combinatorica`"];
$Post = ($ContextPath =
DeleteCases[$ContextPath,
"Combinatorica`" | "GraphUtilities`"]; #) &;

Something like:
$PreRead = # /. {str_String :>
StringReplace[
str, {RegularExpression["^s`(.*)"] :> "System`" <> "$1",
RegularExpression["^c`(.*)"] :> "Combinatorica`" <> "$1"}]} &
Of course, this is working at a very low level, so take care.

Related

Programming pattern or library (i.e. idiomatic way) to handle CLI arguments semantic errors?

I have a Haskell application which uses optparse-applicative library for CLI arguments parsing. My data type for CLI arguments contains FilePaths (both files and directories), Doubles and etc. optparse-applicative can handle parse errors but I want to ensure that some files and some directories exist (or don't exist), numbers are >= 0 and etc.
What can be done is an implementation of a bunch of helper functions like these ones:
exitIfM :: IO Bool -> Text -> IO ()
exitIfM predicateM errorMessage = whenM predicateM $ putTextLn errorMessage >> exitFailure
exitIfNotM :: IO Bool -> Text -> IO ()
exitIfNotM predicateM errorMessage = unlessM predicateM $ putTextLn errorMessage >> exitFailure
And then I use it like this:
body :: Options -> IO ()
body (Options path1 path2 path3 count) = do
exitIfNotM (doesFileExist path1) ("File " <> (toText ledgerPath) <> " does not exist")
exitIfNotM (doesDirectoryExist path2) ("Directory " <> (toText skKeysPath) <> " does not exist")
exitIfM (doesFileExist path3) ("File " <> (toText nodeExe) <> " already exist")
exitIf (count <= 0) ("--counter should be positive")
This looks too ad-hoc and ugly to me. Also, I need similar functionality for almost every application I write. Are there some idiomatic ways to deal with this sort of programming pattern when I want to do a bunch of checks before actually doing something with data type? The less boilerplate involved the better it is :)
Instead of validating the options record after it has been constructed, perhaps we could use applicative functor composition to combine argument parsing and validation:
import Control.Monad
import Data.Functor.Compose
import Control.Lens ((<&>)) -- flipped fmap
import Control.Applicative.Lift (runErrors,failure) -- form transformers
import qualified Options.Applicative as O
import System.Directory -- from directory
data Options = Options { path :: FilePath, count :: Int } deriving Show
main :: IO ()
main = do
let pathOption = Compose (Compose (O.argument O.str (O.metavar "FILE") <&> \file ->
do exists <- doesPathExist file
pure $ if exists
then pure file
else failure ["Could not find file."]))
countOption = Compose (Compose (O.argument O.auto (O.metavar "INT") <&> \i ->
do pure $ if i < 10
then pure i
else failure ["Incorrect number."]))
Compose (Compose parsy) = Options <$> pathOption <*> countOption
io <- O.execParser $ O.info parsy mempty
errs <- io
case runErrors errs of
Left msgs -> print msgs
Right r -> print r
The composed parser has type Compose (Compose Parser IO) (Errors [String]) Options. The IO layer is for performing file existence checks, while Errors is a validation-like Applicative from transformers that accumulates error messages. Running the parser produces an IO action that, when run, produces an Errors [String] Options value.
The code is a bit verbose but those argument parsers could be packed in a library and reused.
Some examples form the repl:
Λ :main "/tmp" 2
Options {path = "/tmp", count = 2}
Λ :main "/tmpx" 2
["Could not find file."]
Λ :main "/tmpx" 22
["Could not find file.","Incorrect number."]

How to make a function with two strings as arguments

I'm not entirely sure what I'm doing wrong here. I have tested the code by input and output and it functions as desired no pun intended. :'P
I'm just not setting up this function correctly and I believe it's because my arguments happen to be desirably a string. Where if done correctly "CD" will be inserted into the middle of "ABEF". So, how do I go about doing this?
Thanks!
insertstr(ABEF, CD)
Function insertstr(string1, string2)
nostrmsg = "No string"
fullng = len(string1)
half = len(string1)/2
if half>0 then hfstr1 = mid(string1, 1, half)
str2lng = len(string2)
if str2lng>0 then paste = hfstr1+string2
lshalf = mid(string1, half+1, fullng)
if str2lng+half=str2lng+half then insert = paste+lshalf
End Function
Start with the knowledge that a functions returns a value, a tentative specification of what the function should do, and a basic testing skeleton:
Option Explicit
' returns the string build by inserting m(iddle) into f(ull) at half position
Function insertInto(f, m)
insertInto = "?"
End Function
Dim t, r
For Each t In Array( _
Array("ABEF", "CD", "ABCDEF") _
)
r = insertInto(t(0), t(1))
WScript.Echo t(0), t(1), r, CStr(r = t(2))
Next
output:
cscript 26873276.vbs
ABEF CD ? False
Then learn about Left, Mid, Len, and \ (integer division).
At last, re-write insertInto() so that the result starts with
cscript 26873276.vbs
ABEF CD ABCDEF True

VIM: Why is this function hanging VIM?

I have added the following fine function to my status bar to show which function is currently being edited in C-derived languages:
set statusline+=%{WhatFunctionAreWeIn()}
fun WhatFunctionAreWeIn()
let strList = ["while", "foreach", "ifelse", "if else", "for", "if", "else", "try", "catch", "case"]
let foundcontrol = 1
let pos=getpos(".") " This saves the cursor position
let view=winsaveview() " This saves the window view
while (foundcontrol)
let foundcontrol = 0
" Go to the character before the last open {
normal [{
call search('\S','bW')
" If the character is a ) then go to the character
" preceding the () section
let tempchar = getline(".")[col(".") - 1]
if (match(tempchar, ")") >=0 )
normal %
call search('\S','bW')
endif
let tempstring = getline(".")
for item in strList
if( match(tempstring,item) >= 0 )
let foundcontrol = 1
break
endif
endfor
if(foundcontrol == 0)
call cursor(pos)
call winrestview(view)
return tempstring
endif
endwhile
call cursor(pos)
call winrestview(view)
return tempstring
endfun
However, after a few minutes VIM hangs. Disabling the function prevents the hang, so I feel confident that this function is to blame. Is there anything in there that might hang VIM? Is there a better way to accomplish the task of showing the currently-edited function in the status bar?
Thanks.
The issue is that your strategy for determining whether to keep moving to surrounding braces is too aggressive:
Suppose your cursor is on the f in a preprocessor directive #endif between two functions.
Since you're between two functions, there is no unmatched { for [{ to jump to, so the cursor doesn't move.
Your match() against strList hits the if in #endif, causing the loop to continue.
The loop never exits.
I suspect a ctags-based approach, like #Gowtham suggests, will work better, even if it requires some customization.

Getting current context from within Package

I had something like the following in my notebook.
test1[g_] := (g == 5);
test2[g_] := (g == 6);
tests={"test1", "test2"}
ToExpression[#][5] & /# tests
When I put this code in a package it doesn't work because test1 is now called MyPackage'Private'test1. How can I modify the last line to make this code run both inside package and inside notebook?
Update
Here's why I was doing doing ToExpression as opposed to using Symbols. In retrospect, maybe it's easier to use Symbols instead
I had a function which I call like getGraphs["LeafFree","Planar",!"Tree",...] to get all graphs that are leaf free, planar and not trees. Some of those strings are classes in GraphData, while others were my own classes. For each of my own classes I had a function with identical name, like LeafFree that tested the property. In the notebook, using ToExpression code like above was the quickest way to implement this.
getGraphs[n_Integer, cl__] := getGraphs[{n, n}, cl];
getGraphs[{nmin_Integer, nmax_Integer}, cl__] :=
Module[{maxgraphnum = 100},
customClasses = {"isLeafFree", ! "isLeafFree"};
classes = {cl}\[Backslash]customClasses;
builtinClasses =
GraphData["Classes"] \[Tilde] (Not /# GraphData["Classes"]);
Assert[classes \[Subset] builtinClasses];
isLeafFree[gname_] :=
FreeQ[GraphData[gname, "DegreeSequence"], 0 | 1];
posClasses = Cases[classes\[Backslash]customClasses, _String];
posGroup =
If[posClasses == {}, GraphData[nmin ;; nmax],
GraphData[posClasses, nmin ;; nmax]];
negClasses = classes\[Backslash]posClasses;
negGroups = GraphData[#[[1]], nmin ;; nmax] & /# negClasses;
result = Complement[posGroup, Sequence ## negGroups];
customTest[g_] :=
And ## (ToExpression[#][g] & /# ({cl} \[Intersection]
customClasses));
(*result=Take[result,Min[Length[result],100]];*)
result = Select[result, customTest]
]
I agree with the comments above that you should perhaps have a compelling reason to do this, but here goes. Here is a code I use in such cases, which allows your symbol to be parsed in whatever context you like, at run-time:
SetAttributes[ParseTimeNameSpaceWrapper,HoldFirst];
Options[ParseTimeNameSpaceWrapper] = {
LocalizingContext->"MyLocalizingContext`",
DefaultImportedContexts:>{"Imported1`", "Imported2`"},
ExtraImportedContexts:> {}
};
ParseTimeNameSpaceWrapper[code_,opts:OptionsPattern[]]:=
Module[{result,
context = OptionValue[LocalizingContext],
defcontexts = OptionValue[DefaultImportedContexts],
extraContexts = OptionValue[ExtraImportedContexts],
allContexts},
allContexts = {Sequence##defcontexts,Sequence##extraContexts};
BeginPackage[context,If[allContexts==={},Sequence##{},allContexts]];
result = code;
EndPackage[];
result
];
You can use options to specify some contexts where these symbols exist, that you want to import during the parse stage. You can call this from any package or notebook, and the symbol will be parsed according to whatever context you specify.
HTH
Edit:
Responding to a comment (since it made the question more specific): There is no question that at run-time Context[] will display whatever is the current context from where the function was called (Global in that case). I meant something else: Context has a syntax Context[symbol], to give a context of any symbol if it is on the $ContextPath. For example, Context[getGraphs] returns Bulatov'showGraphs'. Therefore, if you need to determine the context of some exported function automatically, you call Context[function]. You can use this to construct full names of other (private) functions of that package. Here is a self - contained example:
In[1]:=
BeginPackage["MyTest`"];
f[x_, y_, context_: Context[f]] :=
Module[{f1str = "function1", f2str = "function2", f1, f2},
{f1, f2} = ToExpression[context <> "Private`" <> #] & /# {f1str, f2str};
f1[x, y];
f2[x, y];];
Begin["`Private`"];
function1[x_, y_] := Print["In function1: arguments are ", x, " , ", y];
function2[x_, y_] := Print["In function2: arguments are ", x, " , ", y];
End[]
EndPackage[];
Out[6]= "MyTest`Private`"
In[8]:= f[1, 2]
During evaluation of In[8]:= In function1: arguments are 1 , 2
During evaluation of In[8]:= In function2: arguments are 1 , 2
where x,y are just some sample arguments. Then, you never actually supply the last argument, but you can use the context variable inside your function, to construct long names for your other functions, as in the sample code above. Or you could just plain use Context[f] inside body of the function, and not add any arguments to it.
ToExpression uses the current binding of $Context when creating symbols, so you can force your expression to be interpreted within a particular context thus:
Block[{$Context="MyPackage`Private`"}, ToExpression[#][5]] & /# tests
I'm not sure I understand the circumstances of the original question. You can get the current context using $Context or Context[]... but ToExpression will automatically use the current context without intervention.
If I run the exhibited code in a notebook, it works fine. If I run it like this:
Begin["MyPackage`Private`"]
test1[g_] := (g == 5);
test2[g_] := (g == 6);
tests = {"test1", "test2"}
ToExpression[#][5] & /# tests
End[]
... it also works fine. I can get it to fail if I run it like this:
(* in the package file *)
Begin["MyPackage`Private`"]
test1[g_] := (g == 5);
test2[g_] := (g == 6);
End[]
(* in the notebook *)
tests = {"test1", "test2"}
ToExpression[#][5] & /# tests
... which not only fails but also creates spurious symbols in the notebook's context. You can work around this problem using the Block recipe from above.
If you want to capture the context that was in effect at the moment the package code was loaded, you can do something like this:
(* in the package *)
Begin["MyPackage`Private`"]
test1[g_] := (g == 5);
test2[g_] := (g == 6);
tests = {"test1", "test2"};
With[{context = $Context},
runTests[] := Block[{$Context = context}, ToExpression[#][5]] & /# tests
]
End[]
(* in the notebook *)
MyPackage`Private`runTests[]
runTests uses With to inject the private package context into its definition.
As Janus' noted, it is better to use symbols than strings since they automatically manage the whole context issue -- but this assumes your actual use case will permit the use of symbols.

Equivalent of "defined" in Mathematica

I need a function that takes the name of a symbol as a string and returns whether that symbol is already defined. The function ValueQ is close but it returns False for function names. Also, it takes symbols rather than strings.
Examples:
defined["N"] --> True (predefined function N)
defined["x"] --> False
x = 7;
defined["x"] --> True (x is now defined)
defined["7"] --> True (7 is a number)
f[x_] := 2x
defined["f"] --> True (f has DownValues)
g[x_][y_] := x+y
defined["g"] --> True (g has SubValues)
PS: Thanks to Pillsy for pointing out the need to check for both DownValues and SubValues.
I cobbled this together, which seems to work:
defined[s_] := ToExpression["ValueQ[" <> s <> "]"] ||
Head#ToExpression[s] =!= Symbol ||
ToExpression["Attributes[" <> s <> "]"] =!= {} ||
ToExpression["DownValues[" <> s <> "]"] =!= {} ||
ToExpression["SubValues[" <> s <> "]"] =!= {}
Hopefully there's a prettier solution.
PS: Thanks to Pillsy for pointing out the need to check for both DownValues and SubValues.
I think Names should do the trick:
Names["string"] gives a list of the
names of symbols which match the
string.
If Names["foo"] returns {}, then there should be no definitions for foo, otherwise it should return {"foo"}.
So your function 'defined' might be done as:
defined[str_] := Names[str] != {}
For symbols at least, because this doesn't work for "7", since 7 is not a symbol. You could handle this case seperately, for instance with NumberQ.
Also, you can use Symbol to make a symbol out of a string (useful for automatically generating symbols) and Definition to check the definitions of a symbol.
Symbol["name"] refers to a symbol with
the specified name.
Definition[symbol] prints as the
definitions given for a symbol.
EDIT: Better than looking at what Names returns, NameQ["name"] tells you if a given name exists. Still doesn't tell you if the symbol has an explicit definition though, just that it has been mentioned.
You can use DownValues to see if you have "functions" associated with a symbol. This will work for definitions like
f[x_, y_] := x + y
or
g[3] = 72 * a;
It won't work for exotic things like
h[a_][b] = "gribble";
but most people won't think of that as defining a function anyway. If you want to check for the existence of a function definition, you need to convert the name to an expression (and make sure it's wrapped in Hold when you do!). Here's a reasonably robust function that checks for both DownValues and SubValues:
functionNameQ[name_String] :=
With[{ hSymbol = ToExpression[name, InputForm, Hold] },
MatchQ[hSymbol, Hold[_Symbol]] &&
((DownValues ## hName) =!= {} || (SubValues ## hName) =!= {})];
defined[str_] := Not[ToString[FullDefinition[str]] === ""]

Resources