[SciPy-dev] some scipy.io.mio problems
Alexander Schmolck
a.schmolck at gmx.net
Thu Nov 24 13:54:39 CST 2005
Hi,
I've recently patched mio.py in my ubuntu install of scipy with svn repository
code because I needed to read v6 matlab files. I think I've found some
problems that are still present in the latest svn version (just checked)
Firstly
line 557 (in _parse_mimatrix)
if type == mxCHAR_CLASS:
should read
if dclass == mxCHAR_CLASS
I also suspect line 624 should be s/KeyError/(KeyError,AttributeError)/, i.e.
try:
res = res + _unit_imag[imag.dtypechar] * imag
except (KeyError,AttributeError):
res = res + 1j*imag
Finally loadmat searches sys.path for the mat file. It's not obvious to me why
that would be a good idea, but shouldn't it at least return the *first* match?
I.e. shouldn't that be (in line 735):
full_name = test_name; break
as opposed to just
full_name = test_name
Finally, as a mere suggestion, I'd find it convenient if mat_struct were
either made a bit more featureful or a part of the official interface for
which the user is free to supply a drop-in replacement (with a __repr__
method, for example).
For example, I currently use my somewhat baroque `EasyStruct' class (which
includes __repr__ and most of the features of a dict) to get a more covenient
container for the loaded mat file as follows:
scipy.io.mio.mat_struct = EasyStruct
res = EasyStruct(**loadmat(bla))
'as
----8<----Code for EasyStruct----8<------
class EasyStruct(object):
r"""
Examples:
>>> brian = EasyStruct(name="Brian", age=30)
>>> brian.name
'Brian'
>>> brian.age
30
>>> brian.life = "short"
>>> brian
EasyStruct(age=30, life='short', name='Brian')
>>> del brian.life
>>> brian == EasyStruct(name="Brian", age=30)
True
>>> brian != EasyStruct(name="Jesus", age=30)
True
>>> len(brian)
2
Call the object to create a clone:
>>> brian() is not brian and brian(name="Jesus") ==
>>> EasyStruct(name="Jesus", age=30)
True
Conversion to/from dict:
>>> EasyStruct(**dict(brian)) == brian
True
Evil Stuff:
>>> brian['name', 'age']
('Brian', 30)
>>> brian['name', 'age'] = 'BRIAN', 'XXX'
>>> brian
EasyStruct(age='XXX', name='BRIAN')
"""
def __init__(self,**kwargs):
self.__dict__.update(kwargs)
def __call__(self, **kwargs):
import copy
res = copy.copy(self)
res.__init__(**kwargs)
return res
def __eq__(self, other):
return self.__dict__ == other.__dict__
def __ne__(self, other):
return not self.__eq__(other)
def __len__(self):
return len([k for k in self.__dict__.iterkeys() if not
(k.startswith('__') or k.endswith('__'))])
# FIXME rather perverse
def __getitem__(self, nameOrNames):
if isString(nameOrNames):
return self.__dict__[nameOrNames]
else:
return tuple([self.__dict__[n] for n in nameOrNames])
# FIXME rather perverse
def __setitem__(self, nameOrNames, valueOrValues):
if isString(nameOrNames):
self.__dict__[nameOrNames] = valueOrValues
else:
for (n,v) in zip(nameOrNames, valueOrValues):
self.__dict__[n] = v
def __contains__(self, key):
return key in self.__dict__ and not (key.startswith('__') or
key.endswith('__'))
def __iter__(self):
for (k,v) in self.__dict__.iteritems():
if not (k.startswith('__') or k.endswith('__')):
yield k,v
def __repr__(self):
return mkRepr(self, **vars(self))
def isString(obj):
return isinstance(obj, basestring)
def mkRepr(instance, *argls, **kwargs):
r"""Convinience function to implement ``__repr__``. `kwargs` values are
``repr`` ed. Special behaviour for ``instance=None``: just the
arguments are formatted.
Example:
>>> class Thing:
... def __init__(self, color, shape, taste=None):
... self.color, self.shape, self.taste = color, shape, taste
... def __repr__(self):
... return mkRepr(self, self.color, self.shape,
taste=self.taste)
...
>>> maggot = Thing('white', 'cylindrical', 'chicken')
>>> maggot
Thing('white', 'cylindrical', taste='chicken')
>>> Thing('Color # 132942430-214809804-412430988081-241234', 'unkown',
>>> taste=maggot)
Thing('Color # 132942430-214809804-412430988081-241234',
'unkown',
taste=Thing('white', 'cylindrical', taste='chicken'))
"""
width=79
maxIndent=15
minIndent=2
args = map(repr, argls) + ["%s=%r" % (k, v)
for (k,v) in ipsort(kwargs.items())]
if instance is not None:
start = "%s(" % instance.__class__.__name__
args[-1] += ")"
else:
start = ""
if len(start) <= maxIndent and len(start) + len(args[0]) <= width and \
max(map(len,args)) <= width: # XXX mag of last condition bit
arbitrary
indent = len(start)
args[0] = start + args[0]
if sum(map(len, args)) + 2*(len(args) - 1) <= width:
return ", ".join(args)
else:
indent = minIndent
args[0] = start + "\n" + " " * indent + args[0]
return (",\n" + " " * indent).join(args)
More information about the Scipy-dev
mailing list