Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
Is there a way to separate open Mathematica notebooks so that they don't share any variables? How about making it so some variables are shared but not all?
Yes, there is. I recommend reading documentation related to Mathematica contexts. In a nutshell, all variables belong to some context (namespace), and all variables can be accessed via their fully-qualified names of the form "ContextName`varName". If you just use "varName", Mathematica will search contexts in $ContextPath (try evaluating the variable $ContextPath to see what it is), and will use the first context where it finds that variable. In addition, each notebook specifies a context (stored in the variable $Context) where all its variables are stored (unless fully-qualified name is used).
By default, for all notebooks the context is "Global`". Also by default, $ContextPath for all notebooks includes the "Global`" context (as well as "System`" and some others). The net result is that variables are shared across notebooks, and this can rather quickly become annoying. However, there's an easy solution. To create a "private" context for a notebook, evaluate the following:
SetOptions[EvaluationNotebook[], CellContext -> Notebook]
This notebook will be assigned a unique context (evaluate the variable $Context to see what it is). Also, global context will be removed from ContextPath (try evaluating $ContextPath before and after the SetOptions[...] above to see what's going on.)
[Update: As pointed out by rcollyer on the new Mathematica stack exchange, to set this option as the default for new notebooks, do the following: open the Options Inspector (Ctrl+Shift+O), change the scope (in the dropdown on the top) from "Selection" to "Global Preferences"; on the left expand the nodes Cell Options -> Evaluation Options, and change the CellContext setting to "Notebook."]
Now, here's how to create a shared context:
Begin["SharedContext`"];
varShared1 = "Shared string";
End[];
Alternatively, you could've just typed
SharedContext`varShared1 = "Shared string";
Now you can either use the fully qualified names ("SharedContext`varShared1" will work in any notebook), or you can add the context to $ContextPath:
AppendTo[$ContextPath, "SharedContext`"]
If you do this in all notebooks, varShared1 will become visible without a fully-qualified name.
To summarize, context work a lot like many other search paths. However, there are many subtleties (for example, if a symbol has already been defined in some other context, the Begin["SharedContext`"]/End[] block might not work as you expect -- the existing context of the symbol will be used instead of SharedContext`), so I recommend a healthy dose of experimentation and perusing the docs.
I'm not really sure if this is a wise thing to do, but anyway.
Here is a schematic solution for two Notebooks. It may be generalized, but it's not straightforward.
Open two Notebooks
In each of them go to the menu
(evaluation -> Notebook's default
context -> Unique to this Notebook)
With this, the symbols are not shared anymore.
In each Notebook enter something
like Context[] to get the Notebook
Context
Now in each Notebook enter the
following code
.
Needs["Experimental`"];
SetAttributes[f, HoldFirst];
f[s_, val_] := ToExpression#StringJoin["Notebook$$17$799580`",
ToString#Unevaluated#s, "=", ToString#val];
ValueFunction[t] = f
Where the Notebook$$17$799580 is the context of THE OTHER Notebook (this should be able to be obtained "automatically", but this is a proof of concept only.
Now when you want to share a symbol enter
f[symbolToShare]
That's it.
You may share the value bidirectionally, or just in one direction, entering f[x] only in the Notebook you want as source value for x. The other Notebook will get the updated value, but it'll not update it back.
HTH!
Edit
Towards automation:
You may get all other open Notebook Contexts to update your shared symbols as:
ctxs[]:= Complement[Contexts["Notebook$$*"],
Flatten#Union[{Context[]},
StringCases[Contexts["Notebook$$*"], __ ~~ "Private" ~~ __]]]
So your f will become something like this (not tested)
f[s_, val_] := ToExpression#StringJoin[#,
ToString#Unevaluated#s, "=", ToString#val]&/#ctxs[];
To give all notebooks unique contexts open Options Inspector and set
Cell Options → Evaluation Options → Cell Context to Notebook.
Related
Problem: When I just declare a variable, GoLand immediately highlights it with an error like: "The variable is not used anywhere"; I don't like this behavior of the IDE. I have not yet had time to use it anywhere, but only announced it.
Actually, subject, tell me, please, how to remove this syntax highlighting (namely, about unused variables) in GoLand?
P.S.
There is no benefit from manipulating the: Settings -> Editor -> Inspections -> Go
This does not seem possible with Goland, of VsCode Go (which has the same behavior)
Considering an unused variable is an error for Go itself, the IDE simply reflects that.
It can be jarring though, and other Goland issues reflect this: for example, GO-2374 mentions the same kind of issue with exported functions:
All exported functions (starting with a capital letter) that are not used within a library itself, are marked as unused.
This seems odd to me. Most exported functions in a library are never used within the library itself, but I think it is wrong to mark them as unused since they are not primarily meant to be used within the library.
I still prefer the current highlight, as it makes sure I do not introduce a new variable without using as soon as possible.
Perhaps if you have that new var, do a
_ = yourVar after that.
(Then it is in use)
Warning: scan for "_ =" afterwards yourself to see if you still have these.
The fact that the editor "complains" is just Go. Go doesn't allow you to declare vars that are not in use.
This is a repeat of this question. It seems that I can't view instances of my classes in the variable explorer in Python, when I'm debugging.
There the answer claims that this is resolved, so I'm wondering what I'm doing wrong.
(Spyder maintainer here) By default we show builtins (ints, floats, strings, list, dicts and tuples), Numpy arrays and Dataframes in our Variable Explorer.
If you want to see all objects present in your namespace, you need to go to the menu
Tools > Preferences > Variable Explorer
and turn off the option called
Exclude unsupported data types
I have 2 notebooks in Mathematica. I need to open nb B from nb A and get a value of some parameters (List) with known names. How can I do it without running nb B?
I think you want the functions
NotebookOpen[]
and
NotebookFind[]
but without more information about what you want to do it's difficult to be more specific than this. I'm surprised that your searches of the Mathematica documentation didn't lead you to these functions (and their relatives) already.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am trying to get started with Lisp and I have some (messy) code that i want to be able to ask the user for a title and url.
Save them in a variable, and then print them out when called. I am running into troubles though. First of all i don't know how to compile my program to run it. Also, the one time when i did run it i got an error about the variable title being uncalled. Can anyone help me with either of these things? Sorry i can't give you more information about the error.
;;Define a function called make-cd that takes four parameters
(defun make-url( title url ))
(list :title title :url url)
;;In the make-url function create a plist that takes the passed values
;; Define global variable db and set its value to nil
(defvar *db* nil)
;; Define a function that takes one paramter and pushes it to the make-url func.
;;(defun add-url (url) (push url *db*))
;; Define a function that takes the *db* variable and makes the output pretty
(defun dump-db ()
(dolist (url *db*)
(format t "~{~a:~10t~a~%~}~%" url)))
(defun prompt-read (prompt)
(format *query-io* "~a: " prompt)
(force-output *query-io*)
(read-line *query-io*))
Perhaps this will help.
Lisp programs aren't always distributed in compiled form. Having your program as just the source code is even better then only having the FASL (that's how Lisp binaries are called) because it makes it easier to fix problems if they are found later.
Traditionally, more complex programs, are arranged by means of ASDF package asdf:defsystem macro. You can read more about it here: http://common-lisp.net/~mmommer/asdf-howto.shtml . You can find examples on the internet, of how this is usually done through using Quicklisp and looking into its ~/quicklisp/dists/quicklisp/software/<name of the program>/ directory to see how other programs are arranged.
Once system is defined by asdf:defsystem, you would use asdf:oos to "operate" on it, that is load it. However, Quicklisp has become a very popular and easy to use utility for working with Lisp systems (it uses ASDF package underneath too). So, considering you have it, you would then (ql:quickload "your-system").
In order to make your system available locally through Quicklisp, I'd recommend doing it this way: In your $HOME directory (on Linux it is usually aliased with tilde ~) in the file: ~/.config/common-lisp/source-registry.conf (you may need to create one, if it's not there already), add something like:
(:source-registry
(:tree (:home "quicklisp/quicklisp/"))
(:tree (:home "Projects/my-project/"))
:inherit-configuration)
The above would imply that ~/Projects/my-project/ directory contains a system definition file (*.asd), where you have described what files belong to the system and instructed on how to load them etc.
For other options for adding local projects, read the Quicklisp FAQ
For more information about source-registry.conf file format read ASDF manual.
This is a bit involved at the beginning, so I'd advise you to just install one project using Quicklisp and study how it is made. Alexandria could be a good start - besides being a generally useful package, it isn't very large and illustrates the matter very well, IMO.
The code you have provided contains errors and will not compile. The error is in your definition of make-url. The proper definition should be:
(defun make-url( title url )
(list :title title :url url))
Notice the difference in parenthesis placements.
In your code you had an additional parenthesis following the parameter list. This closed the defun, causing make-url to be evaluated as a function with no body. The next line was then evaluated as a call to the built-in function list. The arguments were evaluated, and an error was encountered when it attempted to find a value for title. There is no binding in the global environment, a binding for title only exists within the body of make-url.
Also, your definition of add-url is commented out. A semi-colon begins a comment in Lisp.
How to compile and run your program depends on what compiler you are using. If you are using SBCL the function is sb-ext:save-lisp-and-die. A simple program like this would usually be run in a Read-Eval-Print-Loop(REPL), and most compilers will enter one when started. If you have SBCL installed you can start a repl by entering the command 'SBCL' to the command prompt. If your code is in an external file you can then load that using Load.
I want to setup aliases for Mma functions in a proper manner.
Currently, I copy and paste several aliases to a cell in a new notebook like:
tf:=TableForm
fi:=FactorInteger
re:=RegularExpression
and so forth.
When I searched for aliases in the doc I found descriptions of the Esc ... Esc method, and a chapter on Defining Custom Notation. I hoped to find some initialization file for defining aliases, I suppose. I am somewhat confused at the moment.
Question:
- What is the common / proper / best way to define function aliases that you use in any new Notebook ?
To define the input aliases for your specific notebook, you need to append them to the default ones. So code like
SetOptions[EvaluationNotebook[],
InputAliases -> Join[InputAliases/.Options[EvaluationNotebook[], InputAliases],
{"tf" -> TableForm, "fi" -> FactorInteger, "re" -> RegularExpression}]]
will do the trick. (Although, this will not overwrite existing aliases of the same name. So you have to be more careful if need to redefine an existing alias.)
To add these aliases to all notebooks, you can:
use the above code on the $FrontEnd object (instead of a Notebook object).
use the Option Inspector (Global Preferences) > Editing Options > InputAliases and use the interface provided.
(This can also be used to change the aliases for any open notebook by selecting it from the dropdown menu.)
or you can follow Mike's solution and add them to your default stylesheet.
The first two options will add the definitions to the init.m file which should be located at FileNameJoin[{$UserBaseDirectory, "FrontEnd", "init.m"}].
For example, my "init.m" file contains the non-standard input alias "l=" -> \[LongEqual], since I typeset quite a bit of maths.
Also, if you don't want your input alias to expand the "tf" out to the full TableForm, then maybe you could use something like
"tf" -> InterpretationBox[StyleBox["tf", FontSlant -> Italic,
FontColor -> GrayLevel[0.5], Selectable -> False], TableForm]
This keeps the compactness of your original definitions, but does not require the introduction of new symbols to your global context (or a new context). It looks like
To turn the tf into TableForm just select it and press Ctrl-Shift-I, i.e., convert it to InputForm.
Perhaps there will be better suggestions, but one thing you can do is to collect all such definitions is some package (but you don't necessarily need Begin, End, BeginPackage and EndPackage, since your aliases are supposed to live in Global`, if I understand correctly). Then, you can load this package from your init.m, so that it will be loaded automatically when you start M. For init.m files and how to use them, here are some useful past SO discussions:
Init.m considerations and good practices
How to automatically load user-defined functions in mathematica
As another alternative, you can also modify $Pre in the following fashion:
$Pre =
Function[code,
Unevaluated[code] /. {
HoldPattern[tf] :> TableForm,
HoldPattern[fi] :> FactorInteger,
HoldPattern[re] :> RegularExpression
},
HoldAll]
(you could also put this redefinition into init.m if you wish). The difference is that the code modifications are happening at "compile-time" with this method, not run-time, so you don't really create the values for symbols which are the aliases. This may be cleaner in some ways, since the kernel will see exactly the same code as you would write by hand otherwise. This of course assumes that you are not using $Pre already for something else, plus that you only work interactively in the FrontEnd.
FWIW I just define these in my stylesheet:
Cell[StyleData["Input"],
InputAutoReplacements->{"hw"->"hello world"},
InputAliases->{"tf"->"TableForm"}
]