How to fix Operand error for method and int - python-3.x

I have this simple script but i get an operand error in Line 16
Code:
class Person:
number_of_people = 0
Gravity = -9.5
def __init__(self, name):
self.name = name
Person.add_person()
#classmethod
def number_of_people(cls):
return cls.number_of_people
#classmethod
def add_person(cls):
cls.number_of_people += 1
p1 = Person("joe")
p2 = Person("frank")
print(Person.number_of_peple())
Error message:
Traceback (most recent call last):
File "app4.py", line 19, in <module>
p1 = Person("joe")
File "app4.py", line 7, in __init__
Person.add_person()
File "app4.py", line 16, in add_person
cls.number_of_people += 1
TypeError: unsupported operand type(s) for +=: 'method' and 'int'
What can i do to fix this error?
In this question it say i need to take the varaible name but I only want to increment and not have a variable for that
TypeError: unsupported operand type(s) for +=: 'method' and 'int' (Python)

Your static variable number_of_people and your class method def number_of_people(cls) are named the exact same thing.
Thus when you add one to cls.number_of_people, the interpreter thinks you want to add a number to the class method which doesn't make sense. You have to change the name of one of those things.

Related

Class assignment: object not callable [duplicate]

As a starting developer in Python I've seen this error message many times appearing in my console but I don't fully understand what does it means.
Could anyone tell me, in a general way, what kind of action produces this error?
That error occurs when you try to call, with (), an object that is not callable.
A callable object can be a function or a class (that implements __call__ method). According to Python Docs:
object.__call__(self[, args...]): Called when the instance is “called” as a function
For example:
x = 1
print x()
x is not a callable object, but you are trying to call it as if it were it. This example produces the error:
TypeError: 'int' object is not callable
For better understaing of what is a callable object read this answer in another SO post.
The other answers detail the reason for the error. A possible cause (to check) may be your class has a variable and method with the same name, which you then call. Python accesses the variable as a callable - with ().
e.g. Class A defines self.a and self.a():
>>> class A:
... def __init__(self, val):
... self.a = val
... def a(self):
... return self.a
...
>>> my_a = A(12)
>>> val = my_a.a()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
>>>
The action occurs when you attempt to call an object which is not a function, as with (). For instance, this will produce the error:
>>> a = 5
>>> a()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
Class instances can also be called if they define a method __call__
One common mistake that causes this error is trying to look up a list or dictionary element, but using parentheses instead of square brackets, i.e. (0) instead of [0]
The exception is raised when you try to call not callable object. Callable objects are (functions, methods, objects with __call__)
>>> f = 1
>>> callable(f)
False
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
I came across this error message through a silly mistake. A classic example of Python giving you plenty of room to make a fool of yourself. Observe:
class DOH(object):
def __init__(self, property=None):
self.property=property
def property():
return property
x = DOH(1)
print(x.property())
Results
$ python3 t.py
Traceback (most recent call last):
File "t.py", line 9, in <module>
print(x.property())
TypeError: 'int' object is not callable
The problem here of course is that the function is overwritten with a property.

TypeError: Params.my_params is expected to be <class 'params.MyParams'>, but value {'host': 'txt', 'project': 'txt', 'roi_term_id': 123} is a dict wit

Goal: read in parameters from .yaml to pass to functions during runtime.
I've seen no reference to this error online; so decided to make a post.
I have a user-defined params.yaml:
my_params:
host: txt
project: txt
roi_term_id: 123
# ...
That is read-in by params.py:
import os
from dataclasses import dataclass
from pathlib import Path
import yaml
from decouple import config
from typed_json_dataclass import TypedJsonMixin
#dataclass
class MyParams(TypedJsonMixin):
host: str
project: str
roi_term: str
def __post_init__(self):
self.public_key = config('KEY')
assert isinstance(self.public_key, str)
self.private_key = config('SECRET')
assert isinstance(self.private_key, str)
super().__post_init__()
# ...
#dataclass
class Params(TypedJsonMixin):
my_params: MyParams
# ...
def load_params_dict():
parameter_file = 'params.yaml'
cwd = Path(os.getcwd())
params_path = cwd / parameter_file
if params_path.exists():
params = yaml.safe_load(open(params_path))
else: # If this script is being called from the path directory
params_path = cwd.parent / parameter_file
params = yaml.safe_load(open(params_path))
return params
params_dict = load_params_dict()
print(params_dict)
project_params = Params.from_dict(params_dict)
Traceback:
File "/home/me/miniconda3/envs/myvenv/lib/python3.7/site-packages/typed_json_dataclass/typed_json_dataclass.py", line 152, in __post_init__
expected_type(**field_value)
TypeError: __init__() got an unexpected keyword argument 'roi_term_id'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "path/main.py", line 7, in <module>
from params import project_params
File "/home/me/PycharmProjects/project/path/params.py", line 89, in <module>
project_params = Params.from_dict(params_dict)
File "/home/me/miniconda3/envs/myvenv/lib/python3.7/site-packages/typed_json_dataclass/typed_json_dataclass.py", line 248, in from_dict
return cls(**raw_dict)
File "<string>", line 9, in __init__
File "/home/me/miniconda3/envs/myvenv/lib/python3.7/site-packages/typed_json_dataclass/typed_json_dataclass.py", line 155, in __post_init__
raise TypeError(f'{class_name}.{field_name} '
TypeError: Params.my_params is expected to be <class 'params.MyParams'>, but value {'host': 'txt', 'project': 'txt', 'roi_term_id': 123} is a dict with unexpected keys
2 things, name and dtype.
Subject:
roi_term: str
Name:
Keys' names in params.yaml must be the exact same as the attributes' names in a class (and I assume order).
dtype:
Attribute in class says str, but when the params.yaml file gets parsed it is considered int - since the value in the file is a whole number. I changed str to int in MyParams class.
Thus, roi_term_id from params.yaml conflicted with roi_term from MyParams class.

Why can't I pickle my custom exception in Python

I am using Python 3.6. I defined a custom exception following this page: https://docs.python.org/3.6/tutorial/errors.html
class MyException(Exception):
def __init__(self, a):
self.a = a
Now, if I try to pickle + unpickle this exception, I get the following error:
>> e = MyException(a=1); pickle.loads(pickle.dumps(e))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-44-413e2ac6234d> in <module>
----> 1 e = MyException(a=1); pickle.loads(pickle.dumps(e))
TypeError: __init__() missing 1 required positional argument: 'a'
Does anyone know why?
Seems to be that the Exception baseclass has special treatment for named arguments (likely in its implementation of __new__)
you can fix this by properly calling the base class in your __init__ method:
>>> class MyException(Exception):
... def __init__(self, a):
... super().__init__(a)
... self.a = a
...
>>> pickle.loads(pickle.dumps(MyException(a=1)))
MyException(1,)

superclass method not working as Expected, Why?

This is my self defined class. But error occurs.
>>> class Int(int):
def __add__(self, other):
return super() + other
>>> f = Int(10)
>>> f + 4
Traceback (most recent call last):
File "<pyshell#110>", line 1, in <module>
f + 4
File "<pyshell#108>", line 3, in __add__
return super() + other
TypeError: unsupported operand type(s) for +: 'super' and 'int'
I know replacing return super() + other with return super().__add__(other) solves the problem. But why doesn't the previous code work. I am confused. Can anyone please explain.
I know super() returns a type: <class 'super'>. Then why super.__add__(other) work and super() + other doesn't ?
You need to overload operators in this case to perform the customized addition. Unlike typical scalar addition, python doesn't know how to perform the addition of custom type that you are asking for and hence it complain. There is a good reference available here which will help you as a starting point to do further research.

Python type conversion error

Am trying to print a given result using the str.format() in python but I keep running into an TypeError. Here is my current piece of code that gives me the error:
def Restaurant_calorie_average(rest):
result = []
for item in rest.menu:
result.append(item.calories)
return sum(result)/len(rest.menu)
def Restaurant_str(self: Restaurant) -> str:
return (
"Name: " + self.name + "\n" +
"Cuisine: " + self.cuisine + "\n" +
"Phone: " + self.phone + "\n" +
"Menu: " + Menu_str(self.menu) + "\n"+
"\t Average Price: {0:3.2f}. Average calories {1:}: ".format(Restaurant_price_average(self), str(Restaurant_calorie_average(self))) + "\n\n")
def Collection_str(C: list) -> str:
''' Return a string representing the collection
'''
s = ""
if not C:
return ''
else:
for r in C:
s = s + Restaurant_str(r)
return s
This is the error I get:
Traceback (most recent call last):
File "C:\Users\Sage\workspace\hello\restaurantsg.py", line 229, in <module>
restaurants()
File "C:\Users\Sage\workspace\hello\restaurantsg.py", line 19, in restaurants
our_rests = handle_commands(our_rests)
File "C:\Users\Sage\workspace\hello\restaurantsg.py", line 48, in handle_commands
print(Collection_str(C))
File "C:\Users\Sage\workspace\hello\restaurantsg.py", line 176, in Collection_str
s = s + Restaurant_str(r)
File "C:\Users\Sage\workspace\hello\restaurantsg.py", line 84, in Restaurant_str
"\tAverage Price: {0:3.2f}. Average calories: {1:}".format(Restaurant_price_average(self), Restaurant_calorie_average(self)) + "\n\n")
File "C:\Users\Sage\workspace\hello\restaurantsg.py", line 113, in Restaurant_calorie_average
return float(sum(result)/len(rest.menu))
TypeError: unsupported operand type(s) for +: 'int' and 'str'
What I don't understand is, that another function Restaurant_price_average() in my program has the exact same parameters and returns a float like the Restaurant_calorie_average() and it works just fine in the current program if I remove the Restaurant_calorie_average() part. I tried type converting 'Restaurant_calorie_average()into string, putting float in format {1:3.1f} but it still doesn't seem to work. Can anyone help me with this? The full program is here Rprogram for your reference.
The error means that the items in the result list have strings as calories and not numbers (at least some of them). The sum() function can't work like that because it internally adds the elements to 0, which results in the error you see:
In [1]: sum(['42'])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-1-86653ad6b5d8> in <module>()
----> 1 sum(['42'])
TypeError: unsupported operand type(s) for +: 'int' and 'str'
In [2]: sum([1, 2, '42'])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-2-c2f90238e02a> in <module>()
----> 1 sum([1, 2, '42'])
TypeError: unsupported operand type(s) for +: 'int' and 'str'
The error is not related to the .format() call, because, as you can see in the traceback, it happens inside Restaurant_calorie_average.
You should fix your code (not shown in the question) so that rest.menu items only contain numbers in their calories attribute. Looking at your full code, apparently this part needs to be fixed:
def Dish_get_info() -> Dish:
""" Prompt user for fields of Dish; create and return.
"""
return Dish(
input("Please enter the Dish's name: "),
float(input("Please enter the price of that dish: ")),
input("Please enter the calories in the food: ") # <-- you are not converting
# to float here
)
As a side note, I agree with Kevin's comment that you would have much more readable code if you wrote actual classes with methods, rather than functions. And if you do use functions, it's a widely adopted convention that function names start with lowercase letters.

Resources