Python - Overloading of a method (with operator oveloading) for varying # arguments? - operator-overloading

As a newbie to object oriented, I'm practicing class using this:
import numpy as np
class complex():
def __init__(self, arg1, arg2 = None):
self.real = arg1
if arg2 == None:
self.imag = 0
else:
self.imag = arg2
self.num = np.complex(self.real, self.imag)
def __mul__(self, other):
if np.iscomplex(other):
return np.multiply(self.numb, other.num)
else:
return np.multiply(self.num, other)
def __str__(self):
return "Foo"
def test():
a = complex(3)
b = complex(1, 5)
print(a * b)
if __name__ == "__main__":
test()
I'm trying to overload the operator * simultaneously oveloading the class method __mul__ since I got different permutations of arguments passing in. The above code can do (object, object) or (object, 'int').
How to pass self as the second argument something like ('int', object)?
Things I tried from my basic understanding: (correct me if I'm wrong)
Static method with self as second argument, but inbuilt operators cannot be overloaded in a static method.
Overloading the method __mul__, but not sure on a good-pratice/right-way to force self as second argument.
Appreciate any help in advance. Please comment below if you need more info.

Related

Python Type Hints for Apache beam ValueProvider

How does one use type hints for ValueProvider value types passed to PTransform and DoFn classes?
class MyPTransform(beam.PTransform):
def __init__(self, my_value_provider: ValueProvider):
# How do I enforce my_value_provider has value_type of str
self.my_value_provider = my_value_provider
I can make this a RuntimeValueProvider or StaticValueProvider and test this explicitly:
type(my_value_provider.type) == str
How do others do this? I didn't see anything here: https://beam.apache.org/documentation/sdks/python-type-safety
I don't think there is a way to enforce this with python's type checking, although you could always add your own runtime type check to potentially improve error messages.
Alternatively, you can avoid having to use ValueProvider at all by using Flex Templates instead.
I ended up creating a wrapper value provider like so, opinions/comments welcome.
from typing import Generic, TypeVar
from apache_beam.options.value_provider import ValueProvider, StaticValueProvider, RuntimeValueProvider
T = TypeVar('T')
class TypedValueProvider(ValueProvider, Generic[T]):
"""
Providers a wrapper around beam's ValueProvider to allow specifying value type hints
"""
def __init__(self, value_provider: ValueProvider, value_type: Type[T]):
self.value_provider = value_provider
self.value_type = value_type
assert value_provider.value_type == value_type
def is_accessible(self):
return self.value_provider.is_accessible()
def get(self):
return self.value_provider.get()
if __name__ == '__main__':
svp = StaticValueProvider(str, 'blah')
dvp: TypedValueProvider[str] = TypedValueProvider(svp, str)
print(isinstance(dvp, ValueProvider))
assert 'blah' == dvp.get()
rvp = RuntimeValueProvider('key', str, 'default')
RuntimeValueProvider.set_runtime_options({'key': 'value'})
dvp: TypedValueProvider[str] = TypedValueProvider(rvp, str)
print(isinstance(dvp, ValueProvider))
assert 'value' == dvp.get()

How do I declare the signature of a function that must return one of its arguments? (in any language*)

How does one express the signature for a function that must return an argument (or this) that it receives (is called on), in TypeScript? Is there a programming language where this is possible?*
// In TypeScript (or consider it pseudo-code)
class C {
// EXAMPLE 1 – Not polymorphic
chainable(x): this // MUST not only return some C,
{} // but the same instance it was called on
}
// EXAMPLE 2
function mutate<T>(a: T[], x): T[] // MUST return a, not a new Array
{
/* So that this doesn't compile */ return Array.from(a);
/* But this is OK */ return a;
}
Conversely, how about a function that must return a new instance?
// EXAMPLE 3
function slice<T>(a: T[], x, y): T[] // MUST return a new Array
❌TypeScript
Go 2?
Would the following contract achieve the above?
contract referentiallyIdentical(f F, p P) {
f(p) == p
v := *p
}
type returnsSameIntSlice(type T, *[]int referentiallyIdentical) T
func main() {
var mutate returnsSameIntSlice = func(a *[]int) *[]int {
b := []int{2}
/* Would this compile? */ return &b
/* This should */ return a
}
}
C++20?
Could the above be expressed as a C++ concept?
✅Scala
*Originally, the question was about doing this in TypeScript, but since that isn't possible, I am curious if it is in another language.
Feel free to remove a tag if that language's type system can't express this
You can - in Scala.
Class with a method returning this.type:
class C {
var x = 0
/** Sets `x` to new value `i`, returns the same instance. */
def with_x(i: Int): this.type = {
x = i
this // must be `this`, can't be arbitrary `C`
}
}
In-place sort that guarantees to return exactly the same array (doesn't really sort anything here):
def sortInPlace[A: Ordered](arr: Array[A]): arr.type = {
/* do fancy stuff with indices etc. */
arr
}
If you attempt to return a different array,
def badSortInPlace(arr: Array[Int]): arr.type = Array(1, 2, 3) // won't compile
you'll get an error at compile time:
error: type mismatch;
found : Array[Int]
required: arr.type
def badSortInPlace(arr: Array[Int]): arr.type = Array(1, 2, 3)
^
This is called a singleton type, and is explained in the spec.
In a language with parametric polymorphism, any function of the type
a → a
must be the identity function: since the function is polymorphic in a, it cannot possibly know anything about a, in particular, it cannot possibly know how to construct an a. Since it also doesn't take a world value or an IO monad or something equivalent, it cannot get a value from global state, a database, the network, storage, or the terminal. It also cannot drop the value, since it must return an a.
Ergo, the only thing it can do is to return the a that was passed in.

Passing arguments to instantiate object in Pytest

I have a class which I would like to instantiate using different sets of input parameters, comparing a property on the resultant object to a passed in value.
I am using the indirect flag on #pytest.fixture for the arguments which are sent to the class constructor. I am trying to unpack kwargs in the constructor. Unsuccesfully. This is the error:
TypeError: type object argument after ** must be a mapping, not SubRequest
Code:
import pytest
class MyClass:
def __init__(self, a):
self.a = a
#pytest.fixture
def my_object(request):
yield MyClass(**request)
# first element = arguments to MyClass, second element = value to compare test to
TEST_CASES = [({"a":1}, 1)]
#pytest.mark.parametrize("test, expected", TEST_CASES, indirect=["test"])
def test_1(my_object, test, expected):
assert my_object.a == expected
My goal is to have the object arguments and their test value TEST_CASES in one structure for easy inspection
I've suggest you a working example. Problem was in test code design. The parameter indirect should be True. Indirect parametrization with multiple fixtures should be done as described in docs. And fixture got all params in his request.param attribute.
import pytest
class MyClass:
def __init__(self, a):
self.a = a
#pytest.yield_fixture
def test_case(request):
params, expected = request.param
yield MyClass(**params), expected
# first element = arguments to MyClass, second element = value to compare test to
TEST_CASES = [({"a": 1}, 1)]
#pytest.mark.parametrize("test_case", TEST_CASES, indirect=True)
def test_1(test_case):
my_object, expected = test_case
assert my_object.a == expected

In a scala macro called with an implicit def, how can I get the source statement of the caller to the implicit def as a string?

I'm trying to write an implicit def macro that captures the invoking statement (and preferably nothing else) as a string, that can hopefully be used just by having the desired output object as an implicit parameter. But I'm having some trouble getting it to work with multi line statements.
For example:
case class HowWasICalled(statement:String, lineNumber:Int)
object HowWasICalled {
implicit def generate: HowWasICalled = macro macro_impl
}
def callMe(something: Any)(implicit context: HowWasICalled)
// macro: c is the blackbox Context
def macro_impl(c: blackbox.Context): c.Expr[HowWasICalled] = { ... }
And the first attempt at implementing a method inside the macro that returns the invoking statement as a string:
def makeString:String = show(c.macroApplication)
But, this only returned "HowWasICalled.generate". I actually wanted the statement invoking callMe.
I was hoping the following would work, but it doesn't. The -Yrangepos compiler flag does not seem to result in range positions in def macros? :(
def makeString:String = {
if (c.enclosingPosition.isRange) {
new String(c.enclosingPosition.source.content.slice(
c.enclosingPosition.start,
c.enclosingPosition.end
))
}
}
The closest I got to any working implementation doesn't exactly capture just statement nor the entire statement, but at least I get the line of source invoking callMe.
def makeString:String = {
val lineNumber = c.enclosingPosition.line
val lineIndex = lineNumber-1
c.enclosingPosition.source.lineToString(lineIndex)
}
How can I improve the macro to handle the following case? It should ideally generate something like a HowIWasCalled("callMe( 1 + 2 )", 123) given the following input
0; 0; 0; val x = callMe(1 +
2)

summation in python

I am getting an error....and I know what I'm doing wrong, but not sure how to fix it. I understand I can't add a string to a integer...Any ideas, I'd be grateful!
self.variables['gas'] = 'gas'+add
TypeError: Can't convert 'int' object to str implicitly
My code:
class Cars:
def __init__(self, **kwargs):
self.variables = kwargs
def set_Variable(self, k, v):
self.variables[k] = v
def get_Variable(self, k):
return self.variables.get(k, None)
def add_gas(self, add, gas):
self.variables['gas'] = gas+add
def main():
mercedes = Cars(gas = 3)
print (mercedes.get_Variable('gas'))
print(mercedes.add_gas(4))
if __name__ == "__main__": main()
Your method add_gas needs two arguments, you're only passing one to the function. Also you are printing the returning value though there is no return in the function.
This one worked for me:
class Cars:
def __init__(self, **kwargs):
self.variables = kwargs
def set_Variable(self, k, v):
self.variables[k] = v
def get_Variable(self, k):
return self.variables[k]
def add_gas(self, add):
self.variables['gas'] +=add
def main():
mercedes = Cars(gas = 3)
print (mercedes.get_Variable('gas'))
mercedes.add_gas(4)
print (mercedes.get_Variable('gas'))
print ('There are %s gallons of gas in the car.' % mercedes.get_Variable('gas'))
if __name__ == "__main__":
main()
So, I see two independent problems with your code:
In your error message you showed this line:
self.variables['gas'] = 'gas'+add
While in your code, the line is this:
self.variables['gas'] = gas+add
That are two different meanings. The first tries to concat the variable add to the string 'gas' which will fail as add is an integer and Python won’t convert integers to strings implicitely (the error told you that). So you would want to do 'gas' + str(add).
In your main function, you call the add_gas method like this:
mercedes.add_gas(4)
But you actually defined the method with two parameters, add and gas, so this will fail.
What I think is what you want to do is to increase the self.variables['gas'] value by add when the method is called, so you would want to write your method like this:
def add_gas(self, add):
self.variables['gas'] = self.variables['gas'] + add
Note that you can shorten that using the += operator to just this:
def add_gas(self, add):
self.variables['gas'] += add
And finally, I don’t know why you would want to use a dictionary for your locale instance variables, but unless you have a good reason to do that, why not just define a gas property for your car type?