Magic method __repr__ leads to AttributeError with __new__ method - python-2.7

My goal is to give numpy.ndarray a different representation, since I want to represent some arrays with units. Thus, I programmed a class that inherits its attributes/ methods from numpy.ndarray. For the another representation I wanted to use the __repr__ magic method like:
class Quantitiy(np.ndarray):
def __new__(cls, value, unit=None, dtype=None, copy=True, order=None, subok=False, ndmin=0):
value = np.asarray(value)
obj = np.array(value, dtype=dtype, copy=copy, order=order,
subok=True, ndmin=ndmin).view(cls)
obj.__unit = util.def_unit(unit)
obj.__value = value
return obj
def __repr__(self):
prefix = '<{0} '.format(self.__class__.__name__)
sep = ','
arrstr = np.array2string(self.view(np.ndarray),
separator=sep,
prefix=prefix)
return '{0}{1} {2}>'.format(prefix, arrstr, self.__unit)
So far this works fine. However, if I want to access the inherited methods from numpy.ndarray I get a AttributeError because __repr__ cant resolve self.__unit.
I tried to solve this problem with a private method that defines the variable self.__unit and called it within the __new__ method but without success:
class Quantitiy(np.ndarray):
def __new__(cls, value, unit=None, dtype=None, copy=True, order=None, subok=False, ndmin=0):
value = np.asarray(value)
obj = np.array(value, dtype=dtype, copy=copy, order=order, subok=True, ndmin=ndmin).view(cls)
# Here I call the private method to initialize self.__unit.
obj.__set_unit()
obj.__value = value
return obj
def __repr__(self):
prefix = '<{0} '.format(self.__class__.__name__)
sep = ','
arrstr = np.array2string(self.view(np.ndarray), separator=sep, prefix=prefix)
return '{0}{1} {2}>'.format(prefix, arrstr, self.__unit)
# New defined private class.
def __set_unit(self, unit):
self.__unit = util.def_unit(unit)
I can not solve this with something like cls.__unit = util.def_unit(unit) in the __new__ method. I already tried to define a __init__ method after __new__. Moreover, I tried to interchange the private methods with public methods.
What I expect:
>>> array = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
>>> q = Quantity(value, unit="meter / second")
>>> q
<Quantitiy [[1,2,3,4],
[5,6,7,8]] meter/second>
>>> q * q
>>> <Quantitiy [[ 1, 4, 9,16],
[25,36,49,64]] meter**2/second**2>
>>> q.min()
>>> <Quantitiy 1 meter/second>
The actual result is:
>>> array = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
>>> q = Quantity(value, unit="meter / second")
>>> q
<Quantitiy [[1,2,3,4],
[5,6,7,8]] meter/second>
>>> q * q
>>> <Quantitiy [[ 1, 4, 9,16],
[25,36,49,64]] meter**2/second**2>
# Up to here everything works fine.
>>> q.min()
>>> AttributeError: 'Quantitiy' object has no attribute
'_Quantitiy__unit'
Does anyone see the mistake and can help me?

Ok, the answer is - as usual - in the FineManual (and could be found searching for "subclassing numpy ndarray" - which is how I found it actually), and requires implementing __array_finalize__(self, obj) :
import numpy as np
class Quantitiy(np.ndarray):
def __new__(cls, value, unit=None, dtype=None, copy=True, order=None, subok=False, ndmin=0):
value = np.asarray(value)
x = np.array(value, dtype=dtype, copy=copy, order=order, subok=True, ndmin=ndmin)
obj = x.view(type=cls)
obj._unit = unit
obj._value = value
return obj
def __repr__(self):
print("repr %s" % type(self))
prefix = '<{0} '.format(self.__class__.__name__)
sep = ','
arrstr = np.array2string(self.view(np.ndarray),
separator=sep,
prefix=prefix)
return '{0}{1} {2}>'.format(prefix, arrstr, self._unit)
def __array_finalize__(self, obj):
# see InfoArray.__array_finalize__ for comments
if obj is None:
return
self._unit = getattr(obj, '_unit', None)
self._value = getattr(obj, '_value', None)

Related

Is it possible to find all integer solutions?

I wanna get all integer solutions in a limited time, is it possible?
This is a linear, integer constraint satisfaction problem, which can be solved efficiently by OR Tools' CP-SAT. I've modified their example to solve your problem in Python:
from ortools.sat.python import cp_model
class VarArraySolutionPrinter(cp_model.CpSolverSolutionCallback):
"""Print intermediate solutions."""
def __init__(self, variables):
cp_model.CpSolverSolutionCallback.__init__(self)
self.__variables = variables
self.__solution_count = 0
def on_solution_callback(self):
self.__solution_count += 1
for v in self.__variables:
print('%s=%i' % (v, self.Value(v)), end=' ')
print()
def solution_count(self):
return self.__solution_count
def SearchForAllSolutionsSampleSat():
"""Showcases calling the solver to search for all solutions."""
# Creates the model.
model = cp_model.CpModel()
p = [1, 2, 3, 4]
ceq = 30
cgeq = 2
N = len(p)
# Creates the variables
x = [model.NewIntVar(0, 100, f'x{i}') for i in range(N)]
# Create the constraints.
model.Add(sum([xi*pi for xi, pi in zip(x, p)]) == ceq)
model.Add(sum(x) >= cgeq)
# Create a solver and solve.
solver = cp_model.CpSolver()
solution_printer = VarArraySolutionPrinter(x)
status = solver.SearchForAllSolutions(model, solution_printer)
print('Status = %s' % solver.StatusName(status))
print('Number of solutions found: %i' % solution_printer.solution_count())
SearchForAllSolutionsSampleSat()

Mock file read in binary mode in Python 2.7

I'm trying to unit test the file reading in binary in Python 2.7. but failing miserably.
test_my_module:
def test_read_binary(self):
d = {
"offset": [1, 4, 5, 7],
"bytes" : [3, 1, 2, 3]
}
spec = pd.DataFrame(d)
input_file = 'input.bin'
fake_file = StringIO.StringIO('foo\nbar\n')
with mock.patch('my_module.open', return_value=fake_file, create=True):
full_spec = self._tt.read_binary(spec, input_file)
print full_spec
my_module:
def read_binary(self, spec, input_file):
with open(input_file, 'rb') as infile:
def read_data(row):
print 'ROW:', row
infile.seek(row['offset'], 0)
value = infile.read(row['bytes'])
print value
return value
spec['raw'] = spec.apply(read_data, axis=1)
return spec
This produces the following exception:
AttributeError: StringIO instance has no attribute 'exit'
Any suggestions how to go about it?
For reference, I solved the problem using the following function:
def mock_open(self, mock_o=None, data=None):
file_spec = file
if mock_o is None:
mock_o = mock.MagicMock(spec=file_spec)
handle = mock.MagicMock(spec=file_spec)
handle.write.return_value = None
if data is None:
handle.__enter__.return_value = handle
else:
handle.__enter__.return_value = data
mock_o.return_value = handle
return mock_o
def test_read_binary(self):
data = b'\x68\x65\x6c\x6c\x6f\x77\x6f\x72\x6c\x64' # helloworld
d = {
'offset': [0, 4, 5, 7],
'bytes': [3, 1, 2, 3]
}
spec = pd.DataFrame(d)
input_file = 'input.bin'
expected_list = [b'\x68\x65\x6c', b'\x6f', b'\x77\x6f', b'\x72\x6c\x64']
m = self.mock_open(data=StringIO.StringIO(data))
with mock.patch('__builtin__.open', m, create=True):
full_spec = self._tt.read_binary(spec, input_file)
self.assertListEqual(expected_list, full_spec['raw'].tolist())

How I can invoke importing class in other class Python

#!/usr/bin/env python
from __future__ import print_function
import sys
import time
import getopt
import alsaaudio
import numpy
from time import sleep
class A_weight():
def __init__(self):
skaler = 2.361E-14
fix_cur = 0.20565360419770495
A = []
hPa = 4e-11
card = 'default'
array_float = numpy.dtype(float)
stream = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, card)
stream.setchannels(1)
stream.setrate(48000)
stream.setformat(alsaaudio.PCM_FORMAT_S16_LE)
stream.setperiodsize(128)
def A(f):
return (12200**2*f**4/((f**2+20.6**2)*(f**2+12200**2)*numpy.sqrt(f**2+107.7**2)*numpy.sqrt(f**2+737.9**2)))+fix_cur
def listen(self):
glob_leq = 0
liczba_ramek = 0
index_ramek = 0
while True:
try:
l, data = stream.read()
except IOError, e:
error_count += 1
print(" (%d) Error recording: %s" % (error_count, e))
else:
if l==128:
decoded_block = numpy.frombuffer(data, dtype='int16' )
else:
continue
Y = numpy.fft.fft(decoded_block) # fft computing and normalization
Aw = A(numpy.arange(20.,20000,(19980./len(Y))))
Na = Aw*Y
inverse = numpy.fft.ifft(Y)
maks = 32768
array_float = numpy.divide(inverse.real ,float( maks))
array_float = array_float**2
sum_array = numpy.sum(array_float, dtype=float)
glob_leq = glob_leq + sum_array
liczba_ramek += 1
index_ramek += 1
if index_ramek == 375:
index_ramek=0
cis_chwil = numpy.divide(glob_leq, liczba_ramek * 128)
leq =10*numpy.log10(numpy.divide(cis_chwil, hPa))
print (leq)
#A.append(leq)
#print(max(A))
A_weight().listen()
So i trying writing program compute sound pressure level with weighting A.
All work correct but when i want close may code in class I have problem. Because something wrong with invoke to importing class in this case is it alsaaudio.
I get this feedback:
Traceback (most recent call last):
File "rec_A.py", line 64, in <module>
A_weight().listen()
File "rec_A.py", line 37, in listen
l, data = stream.read()
NameError: global name 'stream' is not defined
Do you have any idea
Change each occurrence of stream to self.stream:
class A_weight():
def __init__(self):
skaler = 2.361E-14
fix_cur = 0.20565360419770495
A = []
hPa = 4e-11
card = 'default'
array_float = numpy.dtype(float)
self.stream = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, card)
self.stream.setchannels(1)
self.stream.setrate(48000)
self.stream.setformat(alsaaudio.PCM_FORMAT_S16_LE)
self.stream.setperiodsize(128)
...
def listen(self):
glob_leq = 0
liczba_ramek = 0
index_ramek = 0
while True:
try:
l, data = self.stream.read()
...
This will make it an instance variable, and all other methods of that class (as long as they are passed the self argument) will have access to it through self.stream. See this bit of documentation for more details on instance variables.
Also, this is merely an aesthetic point, but the convention in Python is to use upper camel case for class names, i.e., AWeight instead of A_weight - but this will not affect how your code runs.

Pynmea2 attribute error

I've been using the pynmea2 library, but today I ran a GPGGA message through it and it's throwing an attribute error when trying to access the objects datetime method.
>>> from pynmea2 import parse
>>> a = '$GPGGA,201326.000,3348.5072,N,11809.6409,W,2,20,0.55,37.5,M,-34.3,M,0000,0000*65'
>>> msg = parse(a)
>>> msg
<GGA(timestamp=datetime.time(20, 13, 26), lat='3348.5072', lat_dir='N', lon='11809.6409', lon_dir='W', gps_qual='2', num_sats='20', horizontal_dil='0.55', altitude=37.5, altitude_units='M', geo_sep='-34.3', geo_sep_units='M', age_gps_data='0000', ref_station_id='0000')>
>>> msg.datetime
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Python/2.7/site-packages/pynmea2/nmea.py", line 154, in __getattr__
raise AttributeError(name)
AttributeError: datetime
Here's what line 154 and everything related states in nmea.py:
def __getattr__(self, name):
#pylint: disable=invalid-name
t = type(self)
try:
i = t.name_to_idx[name]
except KeyError:
raise AttributeError(name)
f = t.fields[i]
if i < len(self.data):
v = self.data[i]
else:
v = ''
if len(f) >= 3:
if v == '':
return None
return f[2](v)
else:
return v
Any ideas what this could be?
Thanks for looking at this!
Found it...GPGGA sentences have no date values in their string.
I think you want to access the timestamp attribute of the GPGGA record, using:
>>> from pynmea2 import parse
>>> a = '$GPGGA,201326.000,3348.5072,N,11809.6409,W,2,20,0.55,37.5,M,-34.3,M,0000,0000*65'
>>> msg = parse(a)
>>> msg
<GGA(timestamp=datetime.time(20, 13, 26), lat='3348.5072', lat_dir='N', lon='11809.6409', lon_dir='W', gps_qual='2', num_sats='20', horizontal_dil='0.55', altitude=37.5, altitude_units='M', geo_sep='-34.3', geo_sep_units='M', age_gps_data='0000', ref_station_id='0000')>
>>> msg.timestamp
datetime.time(20, 13, 26)

Derived model filefield not available

I have a base model and derived model from it. base model is not abstract, so it also has table associated with it.
Problem : I create a base instance first and then derived instance. And associate derived instance to base. But I get FileField in my derived class as None, even if its saved and available in parent. Why so? Am I missing something?
Some sample code:
def get_filepath(instance):
return u''+instance.name
def BaseModel(models.Model):
name = models.CharField(max_length=50)
filepath = models.FileField(upload_to=get_filepath,
max_length=255, null=True)
#some other fields
def DerivedModel(BaseModel):
type = models.CharField(max_length=50, null=True, blank=True)
Sample on django shell:
>>> obj = BaseModel.objects.create(name='y')
>>> obj.id
56
>>> obj.save()
>>> obj.id
56
>>> nf=ContentFile("this is dummy text")
>>> obj.filepath.save('dummyfile', nf)
>>> dobj=DerivedModel()
>>> dobj.basemodel_ptr=obj
>>> dobj.save()
>>> dobj.id
56
>>> dobj.filepath
<FieldFile: None>
>>> obj.filepath
<FieldFile: y>
Update: for #dgel's answer:
save_base() does it save the derived object? dobj does not get id after that.
After dobj.save(), it seems attributes in base class are getting overwritten by attributes in derived class.
I added ctime created time in BaseModel with default datetime.datetime.utcnow. So once I save derived object, ctime is updated to save time of derived object.
When I look at the DB through sqlitebrowser, filepath field of the BaseModel row is empty.
>>> dobj.save_base(raw=True)
>>> dobj.id
>>> dobj.save()
>>> dobj.filepath
<FieldFile: None>
>>> obj.ctime
datetime.datetime(2012, 8, 23, 8, 50, 3, 171573)
>>> dobj.ctime
datetime.datetime(2012, 8, 23, 8, 51, 9, 946434)
>>> newdobj = DerivedModel.objects.get(id=dobj.id)
>>> newdobj.ctime
datetime.datetime(2012, 8, 23, 8, 51, 9, 946434)
Thanks.
Try this:
dobj = DerivedModel()
dobj.basemodel_ptr=obj
dobj.save_base(raw=True)