List not passing between methods inside a class definition - python

I am trying to create a simple class that inputs a list then appends to the list with a function called "add" which is also defined in the same class.
I keep getting this error: 'list' object has no attribute 'a'
class try1:
def __init__(self, a=[]):
self.a = a
print(a)
return
def add(self, b=None):
self.a.append(b)
print(a)
return
if __name__ == "__main__":
c=try1(['a', 'b', 'c'])
d = ['d', 'e', 'f']
try1.add(d)

You've got a couple different things going on here which cause this weird-looking error.
The core problem is that you're trying to call add on the class try1, not the instance you just created, in the variable c. Changing try1.add(d) to c.add(d) produces the expected result (if you also remove the print(a) or change it to print(self.a), since a doesn't exist in that scope).
The unrelated-looking error is because you made b a keyword argument. When you try to call try1.add, the first argument becomes self inside the method. Then you get an AttributeError because self is a list, which obviously doesn't have an attribute named a.
Also, you shouldn't use a mutable as a default argument. Additionally, you don't need empty return statements: any function without a return statement implicitly returns None.

A few things here. First of all, fix that indentation. Python is really specific about whitespace. Assuming you fix the indentation, you'll come into a couple of other issues. In your main method, you want to be calling c.add(d) (I think).
You're probably running into an error on line 9, which is the error I think you're talking about. In the scope of your method, the variable a doesn't exist yet. self.a does, though. You probably mean to print self.a.
As a side note, class names in Python should start with an uppercase letter. Numbers are allowed, but I'd really try and avoid them.

Related

In python 3, other than in a user defined function, where else can I use the keyword/statement "pass"?

I understand that you can use "pass" in a user defined function, say, when you do not want to put anything in it at the moment. Where else can I possibly use this keyword? When assigning it to a variable for example, I get an error: my_item = pass Why is this happening and where else can I use this keyword at?
pass is, by itself, an entire statement, and can be used anywhere a statement is expected, but almost always are found in the body of a compound statement.
def foo():
pass
if True:
pass
for x in y:
pass
class Bar:
pass
with foo as bar:
pass
etc.
It is typically used where some statement is needed to fill an otherwise empty code block. Note that since any expression can be used as a statement (a so-called expression statement), you can sometimes use a doc string in place of a pass statement:
class FooError(ValueError):
'''A very specific kind of ValueError'''
instead of
# Legal, but unnecessary
class FooError(ValueError):
'''A very specific kind of ValueError'''
pass
You can only place an expression, not a statement, on the right-hand side of an assignment statement, which is why my_item = pass is a syntax error.

class employee print method

I am studying classes in python programming in jupyter notebooks and google colab.
I don't understand the results with respect to this class.
class employee_constructor():
def __init__(self,name,surname,salary):
self.name=name
self.surname=surname
self.salary=salary
def increasesalary(self,percentage):
self.salary=self.salary*(1+percentage/100)
def displayEmployee(self):
print('this employee is {} and gets {} dollars'.format(emp1.name,emp1.salary))
now I try to print out results:
emp1=employee_constructor('jose','ferro',1000)
emp2=employee_constructor('manolo','rod','1500')
emp1.displayEmployee
print('before increase',emp1.salary)
emp1.increasesalary(5)
emp1.increasesalary(5)
print('after increase',emp1.salary)
print(emp1.salary)
# this line does not give error and does nothing:
emp1.increasesalary
print(emp1.salary)
# this line gives error:
# increasesalary() missing 1 required positional argument: 'percentage'
emp1.increasesalary()
I don't understand why running the method without the parenthesis would not cause any error (actually the method is not run) whereas with the parenthesis (and not passing the neccesary variable through an error)
secondly, how can I avoid such kind of errors? i.e. if the user passes nothing assume vale zero
note:
this question explains init method and was proposed as solution. My question is related but is not answered there
I don't understand why running the method without the parenthesis would not cause any error (actually the method is not run) whereas with the parenthesis (and not passing the neccesary variable through an error)
When you refer a method (function in the context of an object, self is passed implicitly) by object.method the method object is returned. But to actually execute the function you need to call it i.e. use the parentheses.
For fun, save the returned method object as a variable and call that instead, you'll see that you're doing the same thing as they refer to the same object.
Now, when you called emp1.increasesalary(), you didn't pass the required argument percentage leading to the error. Note again, the self (object itself) is passed implicitly.
how can I avoid such kind of errors? i.e. if the user passes nothing assume vale zero
Make the argument a keyword argument with a default value of 0:
def increasesalary(self, percentage=0):
self.salary = self.salary * (1 + percentage / 100)
you can always use a funtion (without parenthesis) in python:
def f():
pass
print(f)
this will not call the function but just print out its memory location. so a line containing the function f itself is a valid python statement; but it does not call the function.
then: you need to use self and not emp1 in your displayEmployee(self) method:
def displayEmployee(self):
print('this employee is {} and gets {} dollars'.format(self.name, self.salary))
better:
def __str__(self):
return f"this employee is {self.name} and gets {self.salary} dollars"
then you can
print(emp1)

unbound method must be called with instance as first argument. - Python

I have a relatively simple class which just changes the values of variables depending on the state.
class SetStates:
def LM_State1():
global p_LM1, p_LM2, p_LM3, p_RR1, p_RR2, p_RR3, p_RF1, p_RF2, p_RF3
p_LM1 = Ra_L*P_j1_s1
p_LM2 = P_j2_s1
p_LM3 = P_j3_s1
p_RR1 = Ra_R*(-1)*P_j1_s1
p_RR2 = (-1)*P_j2_s1
p_RR3 = (-1)*P_j3_s1
p_RF1 = Ra_R*(-1)*P_j1_s1
p_RF2 = (-1)*P_j2_s1
p_RF3 = (-1)*P_j3_s1
Initially I was calling the function within the class like so:
if LM_state == 1:
SetStates.LM_State1()
After realizing I need to initialize it now looks like this.
s=SetStates()
if LM_state == 1:
s.LM_State1()
But am now receiving an error specifying that it has been given 1 argument but expected 0. I am almost certain I am missing something very trivial. If someone could clear this up it would be great, thanks
Class methods (that is to say: any def block defined inside a class definition) automatically get passed the instance caller as their first argument (unless it's defined as a staticmethod but let's not muddy the waters). Since your function definition for LM_State1() doesn't include any arguments, Python complains that you gave it an argument (s) that it doesn't know what to do with.
As #BrenBarn mentions in the comments, your class doesn't make a whole lot of sense from a design perspective if it's just modifying global state, but that's the reason for the error anyway. If you really need this (hint: you don't) you should consider wrapping it in a module, importing the module, and defining all your set_state functions at the top-level of that module.
# stateful.py
def set_state_1():
...
# main.py
import stateful
stateful.set_state_1() # set the state!

Python custom function

I have been working at learning Python over the last week and it has been going really well, however I have now been introduced to custom functions and I sort of hit a wall. While I understand the basics of it, such as:
def helloworld():
print("Hello World!")
helloworld()
I know this will print "Hello World!".
However, when it comes to getting information from one function to another, I find that confusing. ie: function1 and function2 have to work together to perform a task. Also, when to use the return command.
Lastly, when I have a list or a dictionary inside of a function. I'll make something up just as an example.
def my_function():
my_dict = {"Key1":Value1,
"Key2":Value2,
"Key3":Value3,
"Key4":Value4,}
How would I access the key/value and be able to change them from outside of the function? ie: If I had a program that let you input/output player stats or a character attributes in a video game.
I understand bits and pieces of this, it just confuses me when they have different functions calling on each other.
Also, since this was my first encounter with the custom functions. Is this really ambitious to pursue and this could be the reason for all of my confusion? Since this is the most complex program I have seen yet.
Functions in python can be both, a regular procedure and a function with a return value. Actually, every Python's function will return a value, which might be None.
If a return statement is not present, then your function will be executed completely and leave normally following the code flow, yielding None as a return value.
def foo():
pass
foo() == None
>>> True
If you have a return statement inside your function. The return value will be the return value of the expression following it. For example you may have return None and you'll be explicitly returning None. You can also have return without anything else and there you'll be implicitly returning None, or, you can have return 3 and you'll be returning value 3. This may grow in complexity.
def foo():
print('hello')
return
print('world')
foo()
>>>'hello'
def add(a,b):
return a + b
add(3,4)
>>>7
If you want a dictionary (or any object) you created inside a function, just return it:
def my_function():
my_dict = {"Key1":Value1,
"Key2":Value2,
"Key3":Value3,
"Key4":Value4,}
return my_dict
d = my_function()
d['Key1']
>>> Value1
Those are the basics of function calling. There's even more. There are functions that return functions (also treated as decorators. You can even return multiple values (not really, you'll be just returning a tuple) and a lot a fun stuff :)
def two_values():
return 3,4
a,b = two_values()
print(a)
>>>3
print(b)
>>>4
Hope this helps!
The primary way to pass information between functions is with arguments and return values. Functions can't see each other's variables. You might think that after
def my_function():
my_dict = {"Key1":Value1,
"Key2":Value2,
"Key3":Value3,
"Key4":Value4,}
my_function()
my_dict would have a value that other functions would be able to see, but it turns out that's a really brittle way to design a language. Every time you call my_function, my_dict would lose its old value, even if you were still using it. Also, you'd have to know all the names used by every function in the system when picking the names to use when writing a new function, and the whole thing would rapidly become unmanageable. Python doesn't work that way; I can't think of any languages that do.
Instead, if a function needs to make information available to its caller, return the thing its caller needs to see:
def my_function():
return {"Key1":"Value1",
"Key2":"Value2",
"Key3":"Value3",
"Key4":"Value4",}
print(my_function()['Key1']) # Prints Value1
Note that a function ends when its execution hits a return statement (even if it's in the middle of a loop); you can't execute one return now, one return later, keep going, and return two things when you hit the end of the function. If you want to do that, keep a list of things you want to return and return the list when you're done.
You send information into and out of functions with arguments and return values, respectively. This function, for example:
def square(number):
"""Return the square of a number."""
return number * number
... recieves information through the number argument, and sends information back with the return ... statement. You can use it like this:
>>> x = square(7)
>>> print(x)
49
As you can see, we passed the value 7 to the function, and it returned the value 49 (which we stored in the variable x).
Now, lets say we have another function:
def halve(number):
"""Return half of a number."""
return number / 2.0
We can send information between two functions in a couple of different ways.
Use a temporary variable:
>>> tmp = square(6)
>>> halve(tmp)
18.0
use the first function directly as an argument to the second:
>>> halve(square(8))
32.0
Which of those you use will depend partly on personal taste, and partly on how complicated the thing you're trying to do is.
Even though they have the same name, the number variables inside square() and halve() are completely separate from each other, and they're invisible outside those functions:
>>> number
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'number' is not defined
So, it's actually impossible to "see" the variable my_dict in your example function. What you would normally do is something like this:
def my_function(my_dict):
# do something with my_dict
return my_dict
... and define my_dict outside the function.
(It's actually a little bit more complicated than that - dict objects are mutable (which just means they can change), so often you don't actually need to return them. However, for the time being it's probably best to get used to returning everything, just to be safe).

Why can I write some things out-of-order in python but not others?

Please have a look below:
a = 5
print a + b
b = 4
When I try to run the code above, it gives an error:
Traceback (most recent call last):
File "C:/Users/user/Documents/modules/ab.py", line 2, in
print a + b
NameError: name 'b' is not defined
Ok. a + b is called before b is defined. That means Python runs the code in order, starts from top to down.
But, how about this one:
class Data:
def __init__(self):
self.debug_level = 9
self.assign = [0, 0, 0, 0]
self.days = 0
def create_days(self, startTime, endTime):
res = 0
try:
if self.final_days < self.maximum_days:
Above, self.final_days and self.maximum_days are not defined yet either, but it does not give any errors. What is the logic behind it?
Best regards,
You're not actually "running" the code yet. In your example, all you have is a method declaration inside the Data class. In it, Python will not check for the existence of class fields because they may be set at another time, in some other method (Python's classes are malleable in that sense).
If you try to run your create_days method in a new instance of the Data class without setting the values for those fields beforehand, you'll get an error.
It doesn't give any errors because the attributes are not accessed when the class is defined. As soon as you call create_days() you'll have a problem :D
The body of a function is evaluated only when it is called, not when it is defined.
References are only looked up when the code is run. You can put whatever names you like in the create_days() method, and none will be checked until the line containing them is executed.
If you actually executed it, you would get
AttributeError: Data instance has no attribute 'final_days'
To reproduce this:
x = Data()
x.create_days(1,2)
also, you have a try block. I assume this is an excerpt from some other code. The try block is probably swallowing the exception.
Python is an interpreted language, unlike c++ it is not compiled so the body of a function isn't evaluated until it is called.

Categories

Resources