I'm new to Python. I have to do a little exercise. I have two classes RealNumber and ComplexNumber and I need to create a new class, with, as an attribute, a dictionary (dict_number) that contains an integer as a key and a RealNumber or ComplexNumber object as value. In the init method, with parameters *args and **kwargs, each arg in *args must be entered with an increasing integer key (using the dict comprehension) (e.g. {0: RealNumber0, 1: RealNumber1, 2: ComplexNumber0}) while for each arg in kwargs it will be necessary to insert the parameter name: value.
Now, I have already created the classes RealNumber and ComplexNumber, but I'm having issues doing the third class.
How can I create a dict that have an incremental value as key and a tuple (object name, object value) as value?
The dictionary must have this form: {incremental key: (name_object, object value)}
, for example: {0: Realnumber 5, 1: ComplexNumber 1 3i...}
Where 0:
is the incremental key; Realnumber
is the name of the object class; 5
is the value contained by the Realnumber
class object.
...
class NumbersCollection: # I've issues here
def __init__(self, *args, **kwargs):
self.dict_numbers = {key: arg for key, arg in kwargs.items()}
if __name__ == '__main__':
x = RealNumber(5)
y = ComplexNumber(1, 3) #first parameter is the real part, the 2nd is the imaginary part
print(f"Number: {x.number}")
print(f"RealPart: {y.numPart}, ImPart: {y.imPart}")
d = NumbersCollection(a=x, b=y) # I've issues here
...
CodePudding user response:
To be honest, you are asking too many questions in a single question. So there is another answer.
__repr__
You can modify representation
of an object of a class defining __repr__
method on a class:
class SomeClass:
def __init__(self, value: int) -> None:
self.value = value
def __repr__(self):
return f"SomeClass {self.value}"
>>> SomeClass(1)
SomeClass 1
enumerate
You can use enumerate
function on an iterable to iterate objects in a sequence, returning index
as first value and value
of an object as second value
data = {
"a": 1,
"b": 2,
"c": 3,
}
>>> for i, (key, value) in enumerate(data.items()):
... print(i, key, value)
...
0 a 1
1 b 2
2 c 3
Answering your question,
combine this techniques to get the desired answer.
Using __repr__
:
class RealNumber:
def __init__(self, value: int) -> None:
self.value = value
def __repr__(self):
return f"RealNumber {self.value}"
class ComplexNumber:
def __init__(self, value: int, imaginary_part: int) -> None:
self.real_part = value
self.imaginary_part = imaginary_part
def __repr__(self):
return f"ComplexNumber {self.real_part} {self.imaginary_part}i"
Using enumerate
:
class NumbersCollection:
def __init__(self, *args: Union[RealNumber, ComplexNumber]):
self.dict_numbers = dict(enumerate(args))
The use of dictionary comprehension there is not required as dict(enumerate(args))
does the same, but better and cleaner. You can, of course, use them if it is a requirement of your assignment.
class NumbersCollection:
def __init__(self, *args: Union[RealNumber, ComplexNumber]):
self.dict_numbers = {i: value for i, value in enumerate(args)}
Both should produce the same answer.
>>> nums = NumbersCollection(RealNumber(1), ComplexNumber(1, 2))
>>> nums.dict_numbers
{0: RealNumber 1, 1: ComplexNumber 1 2i}
CodePudding user response:
How about this?
class NumbersCollection:
def __init__(self, **kwargs):
self.dict_numbers = {
i: (key, value) for i, (key, value) in enumerate(kwargs.items())
}
>>> nums = NumbersCollection(a=1, b=2)
>>> nums.dict_numbers
{0: ('a', 1), 1: ('b', 2)}