How do I make a test function for a class method? - function

I got this class, and I want to test the call method to see if the class is working properly. I'm implementing a test for testing that class Cooling
works. The test function should verify that the call method returns the
correct results for given values of the arguments T and t (the input into the call method is T and t) How would you solve it? With test function i mean with def test_cooling(): My code is under:
class Cooling:
def __init__(self,h,Ts):
self.h=h
self.Ts=Ts
def __call__(self, T, t):
self.T = T
self.t = t
h = -self.h*(self.T - self.Ts)
self.T = (self.T) + self.t*h
return self.T, self.t
I have tried with
def test_Cooling(self):
c=Cooling()
expected=c.__call__(T,t)
self.assertTrue(expected, msg=None)

To test something, you need to understand what it does.
Cooling.__init__ takes two arguments. c = Cooling(h, Ts).
__call__ should not be called explicitly. It instead lets you call an object like a function: c(T, t). It returns the result of a calculation.
With that in mind, we can write a test to check that it returns what we expect.
You'd also need to test that h, Ts, T, and t are stored correctly. They're all just copies of the input except self.T.
class SampleTest(unittest.TestCase):
def test_Cooling(self):
h = 1
Ts = 2
T = 3
t = 4
newT = -1
expected = (newT,t)
cooling = Cooling(h, Ts)
self.assertEqual( cooling(T,t), expected )
self.assertEqual( cooling.h, h )
self.assertEqual( cooling.Ts, Ts )
self.assertEqual( cooling.t, t )
self.assertEqual( cooling.T, newT )
You'll have to pick a set of values for h, Ts, T, and t, and do the calculation for newT by hand. Or ask who wrote the function for some expected inputs and outputs.
Note that it returns t back unaltered, why is it returned at ll?

Related

Tkinter calling functions within a class

Hi I am having trouble calling functions in tkinter
Here is the code
class Demo(tk.Frame):
def ShowOption(self):
print(self.v1.get())
def __init__(self,controller):
tk.Frame.__init__(self,width=800, height=600)
f = Frame(self)
optionList = ('A', 'B','C')
self.v1 = tk.StringVar()
self.v1.set(optionList[0])
Opt1 = tk.OptionMenu(f, self.v1, *optionList,command = self.ShowOption)
Opt1.grid(row=2,column=2,sticky='w')
f.place(relx = 0.5,rely=0.5,anchor='c')
The problem I have is if I use this method it states the function takes 1 postional argument and none were given but if I use
Opt1 = tk.OptionMenu(f, self.v1, *optionList,command = self.ShowOption() )
The function runs straight away when the class is created.
Any help greatly appreciated.
Callback for the command option of OptionMenu expects an argument which is the selected item.
So either you use lambda to skip the argument:
command=lambda v: self.ShowOption()
Or redefine ShowOption() to accept an argument:
def ShowOption(self, value):
...
do this
command = lambda : self.ShowOption()

Function to convert a decimal into that of any base

I am doing this question via an Online learning platform, and there are test cases assigned which i must pass. The topic is Higher Order Functions.
Here is the question:
Write a function make_decimal_to_n_ary_converter that accepts a number n where 1 < n < 17, and returns a number converter that converts a given decimal number into that of base n.
Below is my code(I am supposed to use an inner function i.e converter(x))
def make_decimal_to_n_ary_converter(n):
def converter(x):
if x==0 or x==1:
return x
i=x
b=('A','B','C','D','E','F')
result = ""
while i>0:
a=i%n #3
if a<10:
result = str(i%n)+result
else:
d=a-10
result = b[d] + result
i=i//n
return result
return converter
#Lines below are not to be changed, part of qn
decimal_to_binary = make_decimal_to_n_ary_converter(2)
decimal_to_octal = make_decimal_to_n_ary_converter(8)
decimal_to_hexadecimal = make_decimal_to_n_ary_converter(16)
Here are some test cases that my code passes:
decimal_to_binary(213)
11010101
decimal_to_octal(213)
325
decimal_to_hexadecimal(213)
D5
make_decimal_to_n_ary_converter(15)(213)
E3
However, my code fails some private test cases, and feedback that i received was that my logic in the while loop is wrong. However, after printing some numbers, i failed to see anything wrong.
Would appreciate any help, thank you!
Solved it. My mistake was that for base cases x , i had to return a string instead.

Writing an exception function

I am currently learning on an online learning platform, and my code has to pass the test cases(included below)
Heres the question:
Write a higher-order function exception_function which will return a function with exceptions. exception_function should take in a function f(x), an integer input, and an integer output, and return another function g(x). The output of g(x) should be the same as f(x), except that when x is the same as the integer input, the output will be returned.
For example, given that we have a function sqrt which returns the square root of the argument. Using new_sqrt = exception_function(sqrt, 7, 2) we obtain new_sqrt, which behaves similarly to sqrt except for new_sqrt(7), where the value of 2 will be returned.
Below is the answer template
from math import *
def exception_function(f, rejected_input, new_output):
"""Your code here"""
pass
#################
#DO NOT REMOVE#
#################
new_sqrt = exception_function(sqrt, 7, 2)
Test Cases:
new_sqrt(9) -expected answer 3
new_sqrt(7) -expected answer 2
Here is what im not sure about.
How to control what f will return without changing f itself?
Thank you very much for your time.
Managed to solve it!
def exception_function(f, rejected_input, new_output):
def inner_function(x):
if x==rejected_input:
return new_output
else:
return f(x)
return inner_function
new_sqrt = exception_function(sqrt, 7, 2)

Evaluate function stored in Matlab cell array

I have a function called objective in Matlab I evaluate by writing [f, df] = objective(x, {#fun1, #fun2, ..., #funN}) in a script. The functions fun1, fun2, ..., funN have the format [f, df] = funN(x).
Inside objective I want to, for each input in my cell array called fun, evaluate the given functions using the Matlab built-in function feval as:
function [f, df] = objective(x, fun)
f = 0;
df = 0;
for i = 1:length(fun)
fhandle = fun(i);
[fi, dfi] = feval(fhandle, x);
f = f + fi;
df = df + dfi;
end
end
I get the following error evaluating my objective.
Error using feval
Argument must contain a string or function_handle.
I do not get how to come around this error.
You need to reference the elements of fun using curly braces
fhandle = fun{i};
PS
It is better not to use i and j as variable names in Matlab
Alternatively, a solution using cellfun.
A more elegant approach using cellfun
function [f df] = objective( x, fun )
[f, df] = cellfun( #(f) f(x), fun );
f = sum(f);
df = sum(df);
Note the kinky use of cellfun - the cellarray is the fun rather than the data ;-)

Want to use a vector as parameter to a function, without having to separate its elements

If I call a matlab function with:
func(1,2,3,4,5)
it works perfectly.
But if I do:
a=[1,2,3,4,5] %(a[1;2;3;4;5] gives same result)
then:
func(a)
gives me:
??? Error ==> func at 11
Not enough input arguments.
Line 11 in func.m is:
error(nargchk(5, 6, nargin));
I notice that this works perfectly:
func(a(1),a(2),a(3),a(4),a(5))
How can I use the vector 'a' as a parameter to a function? I have another function otherfunc(b) which returns a, and would like to use its output as a paramater like this func(otherfunc(b)).
Comma-seperated lists
(CSL) can be passed to functions as parameter list,
so what you need is a CSL as 1,2,3,4,5 constructed from an array.
It can be generated using cell array like this:
a=[1,2,3,4,5];
c = num2cell(a);
func(c{:});
Maybe you could try with nargin - a variable in a function that has the value of the number of input arguments. Since you have a need for different length input, I believe this can best be handled with varargin, which can be set as the last input variable and will then group together all the extra input arguments..
function result = func(varargin)
if nargin == 5: % this is every element separately
x1 = varargin{1}
x2 = varargin{2}
x3 = varargin{3}
x4 = varargin{4}
x5 = varargin{5}
else if nargin == 1: % and one vectorized input
[x1 x2 x3 x4 x5] = varargin{1}
I've written x1...x5 for your input variables
Another method would be to create a separate inline function. Say you have a function f which takes multiple parameters:
f = f(x1,x2,x3)
You can call this with an array of parameter values by defining a separate function g:
g = #(x) f(x(1),x(2),x(3))
Now, if you have a vector of parameters values v = [1,2,3], you will be able to call f(v(1),v(2),v(3)) using g(v).
Just make the function take a single argument.
function result = func(a)
if ~isvector(a)
error('Input must be a vector')
end
end
Since arguments to functions in Matlab can themselves be vectoes (or even matrices) you cannot replace several arguments with a single vector.
If func expects 5 arguments, you cannot pass a single vector and expect matlab to understand that all five arguments are elements in the vector. How can Matlab tell the difference between this case and a case where the first argument is a 5-vector?
So, I would suggest this solution
s.type = '()';
s.subs = {1:5};
func( subsref( num2cell( otherfunc(b) ), s ) )
I'm not sure if this works (I don't have matlab here), but the rationale is to convert the 5-vector a (the output of otherfunc(b)) into a cell array and then expand it as 5 different arguments to func.
Please not the difference between a{:} and a(:) in this subsref.
You could create a function of the following form:
function [ out ] = funeval( f, x )
string = 'f(';
for I = 1:length(x)
string = strcat( string, 'x(' , num2str(I), '),' );
end
string( end ) = ')';
out = eval( string );
end
In which case, funeval( func, a ) gives the required output.
Use eval:
astr = [];
for i=1:length(a)
astr = [astr,'a(',num2str(i),'),']; % a(1),a(2),...
end
astr = astr(1:end-1);
eval(['func(' astr ');']);