Johannes Eble said:
Hello Python community,
I have looked for a Python extension to bring Python nearer to Matlab.
Scipy/ipython has already been suggested and I agree with that (I'd add emacs
to the mix); if you want to migrate you might also be interested in some stuff
I've written (will try to publish it later today; I'll be offline for a month
from end of this week, so I'd like to "flush" this stuff before):
- a high-level python-matlab interface (fairly stable, I think); you can use
matlab functions more or less as if they were normal python functions
(including viewing their doc with `help` and catching exceptions that occur
in them)
- anyplot -- a uniform matlab-like plotting iterface to different backends (at
the moment matlab via above bridge, scipy's xplt and matplotlib); this
should make it easy to switch gradually (chances are it will still be some
time before all of matlab's plotting functionality is available in
matplotlib et al; also different backends are good at different things so
the ability to switch without code change is useful)
- a matrix class that is largely sugar around Numeric arrays (and in principle
also numarray), but unlike other such code around preserves compatiblity to
Numeric arrays, whilst still offering some hack to write transposes and
matrix multiplications etc. conviniently. It also does, inter alia, matlab
style formatting.
All of them are fairly well documented and the first one seems fairly stable
(I've been using it for well over a year with little changes, after trying my
best to eliminate memory bugs); I also use the other two all the time, but
they are patchier, I think.
If you don't see any announcement on the newsgroup by saturday but are
interested feel free to bug me (if I don't get it out by the end of the
weekend, it's unlikely to happen)
'as
P.S. There are a couple of other conveniences someone with a matlab background
might be missing, e.g. it's convienient to save variables. Here is a simple
hack that I often find useful to save and load results from experiments,
especially in interactive sessions:
Here's an (untested) mock-example:
>>> array1 = array([1, 2, 3]); array2=array([]), array3 = array([1])
>>> saveVars('filename', 'array1 array2 array3')
>>> del array1; del array2; del array3
>>> loadVars('filename', 'array1 array2 array3')
>>> array1
array([1, 2, 3])
def loadVars(filename, ask=True, into=None, only=None):
r"""Load variables pickled with `saveVars`.
Parameters:
- `ask`: If `True` then don't overwrite existing variables without
asking.
- `only`: A list to limit the variables to or `None`.
- `into`: The dictionary the variables should be loaded into (defaults
to global dictionary).
"""
filename = os.path.expandvars(os.path.expanduser(filename))
if into is None: into = awmstools.magicGlobals()
varH = loadDict(filename)
toUnpickle = only or varH.keys()
alreadyDefined = filter(into.has_key, toUnpickle)
if alreadyDefined and ask:
print "The following vars already exist; overwrite (yes/NO)?\n",\
"\n".join(alreadyDefined)
if raw_input() != "yes":
toUnpickle = without(toUnpickle, alreadyDefined)
if not toUnpickle:
print "nothing to unpickle"
return None
print "unpickling:\n",\
"\n".join(ipsort(list(toUnpickle)))
for k in varH.keys():
if k not in toUnpickle:
del varH[k]
into.update(varH)
def saveVars(filename, varNamesStr, outOf=None, **opts):
r"""Pickle name and value of all those variables in `outOf` (default: all
global variables (as seen from the caller)) that are named in
`varNamesStr` into a file called `filename` (if no extension is given,
'.bpickle' is appended). Overwrites file without asking, unless you
specify `overwrite=0`. Load again with `loadVars`.
Thus, to save the global variables ``bar``, ``foo`` and ``baz`` in the
file 'savedVars' do::
saveVars('savedVars', 'bar foo baz')
"""
filename, varnames, outOf = __saveVarsHelper(
filename, varNamesStr, outOf, **opts)
print "pickling:\n", "\n".join(ipsort(varnames))
try:
f = None
f = open(filename, "wb")
pickle.dump(dict(zip(varnames, atIndices(outOf, varnames))),
f, 1) # UGH: pickle, unlike pickle doesn't accept bin=1
finally:
if f: f.close()
def loadDict(filename):
"""Return the variables pickled pickled into `filename` with `saveVars`
as a dict."""
filename = os.path.expandvars(os.path.expanduser(filename))
if not splitext(filename)[1]: filename += ".bpickle"
f = None
try:
f = open(filename, "rb")
varH = pickle.load(f)
finally:
if f: f.close()
return varH
def __saveVarsHelper(filename, varNamesStr, outOf,extension='.bpickle',**opts):
filename = os.path.expandvars(os.path.expanduser(filename))
if outOf is None: outOf = awmstools.magicGlobals(2)
if not varNamesStr or not isString(varNamesStr):
raise ValueError, "varNamesStr must be a string!"
varnames = varNamesStr.split()
if not splitext(filename)[1]: filename += extension
if opts.get("overwrite") == 0 and os.path.exists(filename):
raise RuntimeError("File already exists")
return filename, varnames, outOf
def atIndices(indexable, indices, default=__unique):
r"""Return a list of items in `indexable` at positions `indices`.
Examples:
>>> atIndices([1,2,3], [1,1,0]) [2, 2, 1]
>>> atIndices([1,2,3], [1,1,0,4], 'default') [2, 2, 1, 'default']
>>> atIndices({'a':3, 'b':0}, ['a'])
[3]
"""
if default is __unique:
return [indexable
for i in indices]
else:
res = []
for i in indices:
try:
res.append(indexable)
except (IndexError, KeyError):
res.append(default)
return res