I am attempting to make a subclass to simplify the inputs to the scipy.stats.exponweib package as well as add some extra functions. Simplifed the class is in its own files call weibull.py
from scipy.stats import exponweib
# import scipy
class weibull(exponweib):
def __init__(self,beta,nu):
super(weibull,self).__init__(a=1,c=beta,loc=0,scale=nu)
print beta
print nu
def doSomething(self,s):
print(s)
My test script looks something like:
from weibull import weibull
w = weibull(2.6,2600)
print('%0.10f'%w.pdf(1000))
w.doSomething('Something')
It seems as though my __init__ is not running at all, none of the print statements run and an error is thrown on the doSomething routine.
The output in the terminal looks like:
Codes> python weibull_testHarness.py
0.0000000000
Traceback (most recent call last):
File "weibull_testHarness.py", line 5, in <module>
w.doSomething('Something')
AttributeError: 'rv_frozen' object has no attribute 'doSomething'
Per NumPy/SciPy developer Robert Kern's answer, subclass rv_frozen, not exponweib.
Notice that exponweib is an instance of the class exponweib_gen.
In [110]: stats.exponweib
Out[110]: <scipy.stats._continuous_distns.exponweib_gen at 0x7fd799db2588>
exponweib is itself a callable which returns an instance of rv_frozen.
In [107]: exponweib(a=1, c=2.6)
Out[107]: <scipy.stats._distn_infrastructure.rv_frozen at 0x7fd7997282b0>
So following this pattern, by analogy, w = weibull(2.6, 2600) will be an instance of rv_frozen. If you want w to have additional methods, then you'll need to subclass rv_frozen, not exponweib, nor exponweib_gen, nor rv_continuous.
import scipy.stats as stats
class my_frozen(stats._distn_infrastructure.rv_frozen):
def __init__(self, dist, *args, **kwds):
super(my_frozen,self).__init__(dist, *args, **kwds)
print(kwds)
def doSomething(self,s):
print(s)
def weibull(beta, nu):
dist = stats.exponweib # an instance of stats._continuous_distns.exponweib_gen
dist.name = 'weibull'
return my_frozen(dist, a=1, c=beta, loc=0, scale=nu)
w = weibull(2.6, 2600)
print('%0.10f'%w.pdf(1000))
w.doSomething('Something')
yields
{'loc': 0, 'scale': 2600, 'c': 2.6, 'a': 1}
0.0001994484
Something
Related
I am fairly new to Python, and trying to write a wrapper class around some Quantlib swap objects. Problem is that I am trying to call the Qualtlib Schedule object using attributes that have been either passed to the constructor or calculated in the constructor. Problem is when I run the code as such;
import swapleg as sl
Leg1 = sl.SwapLeg("Fix","AUD",ql.Date(26, 9, 2018),ql.Date(26, 9, 2028),ql.Monthly)
print(Leg1.EffectiveDate)
Leg1.showSchedule()
I get the following error
Traceback (most recent call last):
September 26th, 2018
.......
AttributeError: type object 'SwapLeg' has no attribute 'EffectiveDate'
The code is listed - the object Leg1 gets instantiated, and the EffectiveDate does get set. My issue is that when the showSchedule call the Quantlib call ql.Schedule, it loses visibility to the EffectiveDate, even though I am looking it with self.EffectiveDate. Clearly I am missing something here. Any help would be appreciated.
import QuantLib as ql
class SwapLeg:
def __init__(self,LegType,CCY,EffectiveDate=None,TerminationDate=None,Tenor=None,Rate=None,Spread=None):
self.LegType=LegType
self.CCY=CCY
self.Tenor=Tenor
if EffectiveDate is None:
self.EffectiveDate = ql.Settings.instance().evaluationDate
else:
self.EffectiveDate =EffectiveDate
......
def _LegSchedule(self):
ls = ql.Schedule( self.EffectiveDate,
self.TerminationDate,
self.Tenor,
self.Calendar,
self.businessDayConvention,
self.businessDayConvention,
self.GenRule,
self.EndOfMonth,
self.FirstDate,
self.NextToLastDate)
return ls
#classmethod
def showSchedule(self):
for i, d in enumerate(self._LegSchedule(self)):
print("{0} {1}".format(i+1,d))
I'm using Zipline-1.1.1, Python3.4.6 to create a dynamic stock selector as follows:
from zipline.pipeline import Pipeline, engine
from zipline.pipeline.factors import AverageDollarVolume, Returns
def make_pipeline():
dollar_volume = AverageDollarVolume(window_length=1)
high_dollar_volume = dollar_volume.percentile_between(N, 100)
recent_returns = Returns(window_length=N, mask=high_dollar_volume)
low_returns = recent_returns.percentile_between(0, n)
high_returns = recent_returns.percentile_between(N, 100)
pipe_columns = {
'low_returns': low_returns,
'high_returns': high_returns,
'recent_returns': recent_returns,
'dollar_volume': dollar_volume
}
pipe_screen = (low_returns | high_returns)
pipe = Pipeline(columns=pipe_columns, screen=pipe_screen)
return pipe
I initialize a pipeline object with:
my_pipe = make_pipeline()
But when I try to populate the Pipeline, it fails with:
result = engine.PipelineEngine.run_pipeline(my_pipe, '2017-07-10', '2017-07-11')
Traceback (most recent call last):
File "<input>", line 1, in <module>
result = engine.PipelineEngine.run_pipeline(my_pipe, '2017-07-10', '2017-07-11')
TypeError: run_pipeline() missing 1 required positional argument: 'end_date'
I can't figure out what is wrong, any help is much appreciated.
If I understand correctly, you're using this library.
As far as I can see from that code, to be able to use run_pipeline method you have to instantiate on of pipeline engines before, e.g. SimplePipelineEngine. You need that because PipelineEngine is a class, even abstract class, not an object.
So you have to create an object of SimplePipelineEngine class and then call run_pipeline on it. You can do it this way:
your_engine = SimplePipelineEngine(get_loader=your_loader, calendar=your_calendar, asset_finder=your_asset_finder)
your_eninge.run_pipeline(my_pipe, '2017-07-10', '2017-07-11')
Of course you have to create your_loader etc. first.
Here is example of SimplePipelineEngine usage. I hope it will help.
I am trying to extend the Python datetime.timedelta for use with cross country race results. I want to construct an object from a string in format u"mm:ss.s". I am able to accomplish this using the factory design pattern and #classmethod annotation. How would I accomplish the same by overriding __init__ and/or __new__?
With the code below, constructing an object raises a TypeError. Note that __init__ is not called, because 'in my __init__' is not printed.
import datetime
import re
class RaceTimedelta(datetime.timedelta):
def __init__(self, timestr = ''):
print 'in my __init__'
m = re.match(r'(\d+):(\d+\.\d+)', timestr)
if m:
mins = int(m.group(1))
secs = float(m.group(2))
super(RaceTimedelta, self).__init__(minutes = mins, seconds = secs)
else:
raise ValueError('timestr not in format u"mm:ss.d"')
Here is the error:
>>> from mytimedelta import RaceTimedelta
>>> RaceTimedelta(u'24:45.7')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported type for timedelta days component: unicode
>>>
If I move my code from __init__ to __new__, I get the following. Note that this time, the output shows that my __new__ function is called.
>>> RaceTimedelta(u'24:45.7')
in my __new__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "mytimedelta.py", line 16, in __new__
super(RaceTimedelta, self).__new__(minutes = mins, seconds = secs)
TypeError: datetime.timedelta.__new__(): not enough arguments
>>>
Apparently timedelta objects are immutable, which means their value is actually set in the class' __new__() method—so you'll need to override that method instead of its __init__():
import datetime
import re
class RaceTimedelta(datetime.timedelta):
def __new__(cls, timestr=''):
m = re.match(r'(\d+):(\d+\.\d+)', timestr)
if m:
mins, secs = int(m.group(1)), float(m.group(2))
return super(RaceTimedelta, cls).__new__(cls, minutes=mins, seconds=secs)
else:
raise ValueError('timestr argument not in format "mm:ss.d"')
print RaceTimedelta(u'24:45.7')
Output:
0:24:45.700000
BTW, I find it odd that you're providing a default value for thetimestrkeyword argument that will be considered illegal and raise aValueError.
I'm trying to test that a pandas method gets called with some values.
However, just by applying a #patch decorator causes the patched method to throw a ValueError within pandas, when the actual method does not. I'm just trying to test that Stock.calc_sma is calling the underlying pandas.rolling_mean function.
I'm under the assumption that the #patch decorator basically adds some "magic" methods to the thing I'm patching that allow me to check if the function was called. If this is the case, why doesn't the pandas.rolling_mean function behave the same whether it's patched vs. not patched?
app/models.py
import pandas as pd
class Stock: # i've excluded a bunch of class methods, including the one that sets self.data, which is a DataFrame of stock prices.
def calc_sma(self, num_days)
if self.data.shape[0] > num_days: # Stock.data holds a DataFrame of stock prices
column_title = 'sma' + str(num_days)
self.data[column_title] = pd.rolling_mean(self.data['Adj Close'], num_days)
app/tests/TestStockModel.py
def setUp(self):
self.stock = MagicMock(Stock)
self.stock.ticker = "AAPL"
self.stock.data = DataFrame(aapl_test_data.data)
#patch('app.models.pd.rolling_mean')
def test_calc_sma(self, patched_rolling_mean):
Stock.calc_sma(self.stock, 3)
assert(isinstance(self.stock.data['sma3'], Series))
patched_rolling_mean.assert_any_call()
ERROR: test_calc_sma (TestStockModel.TestStockModel)
Traceback (most recent call last):
File "/Users/grant/Code/python/chartflux/env/lib/python2.7/site-packages/mock.py", line 1201, in patched
return func(*args, **keywargs)
File "/Users/grant/Code/python/chartflux/app/tests/TestStockModel.py", line 26, in test_calc_sma
Stock.calc_sma(self.stock, 3)
File "/Users/grant/Code/python/chartflux/app/models.py", line 27, in calc_sma
self.data[column_title] = pd.rolling_mean(self.data['Adj Close'], num_days)
File "/Users/grant/Code/python/chartflux/env/lib/python2.7/site-packages/pandas/core/frame.py", line 1887, in __setitem__
self._set_item(key, value)
File "/Users/grant/Code/python/chartflux/env/lib/python2.7/site-packages/pandas/core/frame.py", line 1967, in _set_item
value = self._sanitize_column(key, value)
File "/Users/grant/Code/python/chartflux/env/lib/python2.7/site-packages/pandas/core/frame.py", line 2017, in _sanitize_column
raise ValueError('Length of values does not match length of '
ValueError: Length of values does not match length of index
>>> import os
>>> os.getcwd()
'/'
>>> from unittest.mock import patch
>>> with patch('os.getcwd'):
... print(os.getcwd)
... print(os.getcwd())
... print(len(os.getcwd()))
...
<MagicMock name='getcwd' id='4472112296'>
<MagicMock name='getcwd()' id='4472136928'>
0
By default patch replaces things with really generic mock objects. As you can see, calling the mock just returns another mock. It has a len of 0 even if the replaced object wouldn't have a len. Its attributes are also generic mocks.
So to simulate behavior requires things extra arguments like:
>>> with patch('os.getcwd', return_value='/a/wonderful/place'):
... os.getcwd()
...
'/a/wonderful/place'
Or to "pass through":
>>> _cwd = os.getcwd
>>> with patch('os.getcwd') as p:
... p.side_effect = lambda: _cwd()
... print(os.getcwd())
...
/
There is a similar example in https://docs.python.org/3.5/library/unittest.mock-examples.html
Sorry if this question is stupid. I created an unittest class which needs to take given inputs and outputs from outside. Thus, I guess these values should be initiated. However, I met some errors in the following code:
CODE:
import unittest
from StringIO import StringIO
##########Inputs and outputs from outside#######
a=[1,2]
b=[2,3]
out=[3,4]
####################################
def func1(a,b):
return a+b
class MyTestCase(unittest.TestCase):
def __init__(self,a,b,out):
self.a=a
self.b=b
self.out=out
def testMsed(self):
for i in range(self.tot_iter):
print i
fun = func1(self.a[i],self.b[i])
value = self.out[i]
testFailureMessage = "Test of function name: %s iteration: %i expected: %i != calculated: %i" % ("func1",i,value,fun)
self.assertEqual(round(fun,3),round(value,3),testFailureMessage)
if __name__ == '__main__':
f = MyTestCase(a,b,out)
from pprint import pprint
stream = StringIO()
runner = unittest.TextTestRunner(stream=stream, verbosity=2)
result = runner.run(unittest.makeSuite(MyTestCase(a,b,out)))
print 'Tests run', result.testsRun
However, I got the following error
Traceback (most recent call last):
File "C:testing.py", line 33, in <module>
result = runner.run(unittest.makeSuite(MyTestCase(a,b,out)))
File "C:\Python27\lib\unittest\loader.py", line 310, in makeSuite
return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
File "C:\Python27\lib\unittest\loader.py", line 50, in loadTestsFromTestCase
if issubclass(testCaseClass, suite.TestSuite):
TypeError: issubclass() arg 1 must be a class
Can anyone give me some suggestions? Thanks!
The root of the problem is this line,
result = runner.run(unittest.makeSuite(MyTestCase(a,b,out)))
unittest.makeSuite expects a class, not an instance of a class. So just MyTestCase, not MyTestCase(a, b, out). This means that you can't pass parameters to your test case in the manner you are attempting to. You should probably move the code from init to a setUp function. Either access a, b, and out as globals inside setUp or take a look at this link for information regarding passing parameters to a unit test.
By the way, here is the source file within python where the problem originated. Might be informative to read.