Why do I need print() when calling a function here? [duplicate] - python

This question already has an answer here:
When running python files in terminal, do return commands not get executed?
(1 answer)
Closed 1 year ago.
I've spent more time than I should trying to solve a code problem this way:
class Rectangle:
def __init__(self, width, height):
self.w = width
self.h = height
def area(self):
# return area
return(self.w * self.h)
w = int(input())
h = int(input())
obj = Rectangle(w, h)
#call the function
obj.area()
I'm trying to call the area function like they call a function in this example:
class Dog:
def __init__(self, name, color):
self.name = name
self.color = color
def bark(self):
print("Woof!")
fido = Dog("Fido", "brown")
print(fido.name)
fido.bark()
But after giving up and looking at some answers and at a similar problem on a different site, people all use this instead:
print(obj.area())
Can somebody explain why I have to use print? It seems redundant but apparently it isn't, because without it, I get no output.

I think in order to help you understand the reason, it is important to understand the difference between a method that returns a value and one that has no return statement.
Firstly, ALL functions return a value. Even those that don't have an explicit return statement (such as your bark method). If no return statement is passed, the method returns value None. You can test this by doing:
print(fido.bark()) # prints None
Now in your area method you are returning a value, not printing it. That is why you have to print the value that gets returned in order to visualize it. That is the difference between the two methods. One returns the actual value, while the other one prints the value and returns None.
Hope that answers your question :) Cheers!

Related

How to assign values to variables directly through a method instead of through an instance

The standard way to compute areas of rectangles using 'class' in Python3 is via something like the following
class Rectangles:
def __init__(self,length,width):
self.a = length
self.b = width
def Area(self):
return self.a*self.b
example = Rectangles(2,3)
print('Area of the specific example=',example.Area())
Obviously, the above code will generate a print of the answer to be equal to 6.
My question: How to hold up the assignment of length=2 and width=3 up until the very last line. In other words, I would like to avoid ''pre-defining'' that example with fixed length and width, so that I could assign length and width directly to Area(), which would lead to direct calculation of areas. Following is my tentative approach (the following code only shows my intention and it doesn't work in Python, and that's why I am wondering about a way to make it work...)
class Rectangles:
def __init__(self,length,width):
self.a = length
self.b = width
def Area(self,length,width): ##I intend to assign values to length and width DIRECTLY in the method Area()
return self.a*self.b
example =Rectangles() ##I would NOT like to assign length and width too early at this stage. How to correctly express that??
example.Area(2,3) ##Inside Area() is where I WOULD like to assign a length and width to example.Area(4,7) ##In this way I don't need to define a fixed example for each given (length, width)
In this way, I don't have to define a bunch of fixed instances (say, example (4,7), example (2,3), etc...) for computing their areas. Could anyone help me out with this?
Thanks in advance!
I don't see why you would need an object-oriented approach here. If you wanted to have an area function organized under Rectangles, use a static method:
class Rectangles:
#staticmethod
def Area(length, width):
return length * width
example = Rectangles()
example.Area(2,3)
example.Area(4,7)
# OR
Rectangles.Area(2,3)
Rectangles.Area(4,7)
I'm not sure why you would need this, though.
If you want to instantiate a Rectangle without providing the params you can define default values in the class constructor:
class Rectangles:
def __init__(self, length=0, width=0):
self.a = length
self.b = width
And to define the length and width values through the Area() method, just add them as parameters:
def Area(self, length, width):
self.a = length
self.b = width
return self.a*self.b
Your 'tentative approach' is not going to work. You have provided two parameters to the initialization method __init__() of your Rectangles class but when you're creating instances, you're not providing those 2 required positional arguments: 'length' and 'width'. This will throw an error.
I think you are trying to have something like the following code.
Code
class Rectangle:
def __init__(self):
pass # Left blank for future use
#staticmethod
def area(self, length, width):
return length*width
example =Rectangle()
example.area(2,3)
example.area(4,7)

How is value assigned to "other" variable in this Python Class?

I am doing this Python Edx course, and one of the examples given during introduction to OOP is below. It is a basic question, lot of you will downvote it, but I need to understand this before I move ahead.
I have already searched on Reddit and asked this question on the Edx forums too, but still don't understand it. I have searched this website too for this specific coding example.
Reddit: https://www.reddit.com/r/learnpython/comments/a54y04/explanation_needed_on_a_simple_class_creation/
class Coordinate(object):
def __init__(self, x, y):
self.x = x
self.y = y
def distance(self, other):
x_diff_sq = (self.x-other.x)**2
y_diff_sq = (self.y-other.y)**2
return (x_diff_sq + y_diff_sq)**0.5
point1 = Coordinate(1,2)
point2 = Coordinate(3,4)
print(point1.distance(point2))
What I want to understand is that how is "other.x" value determined by the program? Because I am nowhere assigning a value to other.x and other.y.
For self.x and self.y, there is an explicit assignment happening, but there is no such assignment for "other.x" and "other.y". How does the program assign "3" to "other.x" and "4" to "other.y"?
other is just the argument that the method distance is taking. It is implicitly expected that this argument has the x and y attributes. Whether they really exist or are assigned or not is not a concern for the method distance.
How does the program assign "3" to "other.x" and "4" to "other.y"?
Again, as said before, other is just the name of the argument of the function. Lets look at the only place where you call the function:
print(point1.distance(point2))
This is interpreted as self.distance(other), so we can conclude that in this particular case, other is the object point2.
Now, lets go back a few lines to find any reference of point2. Here it is:
point2 = Coordinate(3,4)
When doing Coordinate(3,4) we are invoking the __init__ method of the class. So in that method, we assigning x with 3 and y with 4.
So you are right, there is no explicit assignment for other.x and other.y, but other is not really an object but an argument. So you have to understand which object it is for a specific function call, and that trace where it is being assigned.
Don't let argument names confuse you!
For self.x and self.y, there is an explicit assignment happening
This is not entirely true as well. Yes a few lines back there is an assignment to self but that's just the same name for two different functions' arguments. The code could be written like this and still work the same:
class Coordinate(object):
def __init__(obj, x, y):
obj.x = x
obj.y = y
def distance(one, two):
x_diff_sq = (one.x-two.x)**2
y_diff_sq = (one.y-two.y)**2
return (x_diff_sq + y_diff_sq)**0.5
Here you would say that there is no explicit assignment to one. But it all depends on each call of each function, what arguments it is being passed.

Return statement in python function not returning anything [duplicate]

This question already has answers here:
Python: Return possibly not returning value
(5 answers)
Closed 3 years ago.
I don't understand the difference between return and print. I was told that you should use return in function statements but it doesn't return anything, so I've been using print in my functions. But I want to understand why return statements in my functions do not work.
def triangle_area(b, h):
return 0.5 * b * h
triangle_area(20, 10)
I would expect this return the multiplication, but it doesn't yield anything. Please help! And when I replace the return with print, it works perfectly. Am i supposed to use print in functions?
return and print are two very different instructions. Return has the purpose of storing the value that is computed by a function, value that will be used according to the programmer's wish. Print does what it says: it prints whatever you tell him to print.
Using return won't print anything, because this instruction is not built for such a purpose. Only for storing. Nothing more, nothing less. print displays something on the screen.
Like this:
print(triangle_area(20, 10))
Good luck to you all, bro!
It does return the product; what it doesn't do is print it (since you didn't tell it to).
Because you are not printing the return result from the function. Please try:
print(traingle_area(20,30))
You are not receiving the output the function is returning.
print(triangle_area(20, 10))
This will show the result.
It is returning the value, you simply are not capturing it or doing anything with it. For instance:
def triangle_area(b, h):
return 0.5 * b * h
output = triangle_area(20, 10) # capture return value
print(output)
Or as others have suggested, just pass the result straight to the print function if that's what you're looking to do:
def triangle_area(b, h):
return 0.5 * b * h
print(triangle_area(20, 10)) # capture return value and immediately pass to print function
Note that the output will be lost if passed straight to print(). If you want to use it later in your program, the first code block is more appropriate
Functions return a value, so you need to store them in variable.
print(triangle_area(20, 10))

How do you multiply values within a class in python?

class bread:
def __init__(self,grain,cost,number):
self.grain=(grain)
self.cost=int(cost)
self.number=int(number)
def price(self):
p=self.cost*self.number
print(p)
apple=bread("wholemeal",int(2),int(12))
print(apple.grain,apple.cost,apple.number)
print (apple.price)
After I enter this block of code I should expect to see 24, but instead I get:
bound method bread.price of <main.bread object at 0x05CC7430>>
I am new to oop and starting to experiment but I can't find a solution.
You need to call price:
apple.price()
However, variable attribute behavior with methods can be achieved using property:
class bread:
def __init__(self,grain,cost,number):
self.grain=grain
self.cost=cost
self.number=number
#property
def price(self):
return self.cost*self.number
apple=bread("wholemeal",2, 12)
print(apple.price)
In this case you don't seem to want to deal with a class object, but just want to get the output. This you can do like so:
class bread:
def __init__(self, grain, cost, number):
self.grain = (grain)
self.cost = int(cost)
self.number = int(number)
return self.price()
def price(self):
p = self.cost * self.number
print("%s : %d" % (self.grain, p))
bread("wholemeal", 2, 12)
As a beginner you should not worry too much about things like property but keep it as simple (and verbose) as possible. Also because you're making the input for the grain type, I'm guessing you want to print that out together with the value.
To unpack the changes I made to your code as an example for some basic coding practices:
note the spacing between functions
note the spacing between individual items
note how the output is produced with print()
Once all this is done, all we have to do is make the call we would otherwise have to make ourselves everytime, inside __init__. Good luck, and have fun learning python!
When you print the function at the end, you actually need to call the function. Currently you are just getting the instance of the method within the object. But you should be using parenthesis () to call the function when you print it. You also don't need to print the function call to get 24 since you are already printing the output of number and cost within your function. But if you do want to print the function, you can use a return value within your function. Here is an example below:
class bread(object):
def __init__(self, grain, cost, number):
self.grain = grain
self.cost = cost
self.number = number
def price(self):
price = self.cost * self.number
return price
apple=bread("wholemeal", 2, 12)
print(apple.price())
Notice that at the end of the code We actually called the function () when printing it. You will then print the return value of the function. If you wanted to simply print the value within the function, you could call the function at the bottom of the code without printing it like this:
apple.price()
and then choose to put the print statement within the price method. Your output from the code above it 24:
24

Self in python Class - I can do it with out it...? [duplicate]

This question already has answers here:
Why do you need explicitly have the "self" argument in a Python method? [duplicate]
(10 answers)
Closed 6 years ago.
Consider this code:
class example(object):
def __init__ (): # No self
test() # No self
def test(x,y): # No self
return x+y
def test1(x,y): # No self
return x-y
print(example.test(10,5))
print(example.test1(10,5))
15
5
This works as expected. I believe I can write a whole program not using self. What am I missing? What is this self; why is it needed in some practical way?
I have read a lot about it - (stack, Python documentation), but I just don't understand why it's needed, since I can obviously create a program without it.
You can perfectly create a program without it. But then you'd be missing one of the key features of classes. If you can do without self, I'd argue you can do without classes and just do something purely with functions :)
Classes allow you to create objects which have a PROPERTY associated to them, and self allows you to access those values. So say you have a square.
g code:
class Square(object):
def __init__ (self, length, height):
self.length = length # THIS square's length, not others
self.height = height # THIS square's height, not other
def print_length_and_height(self):
print(self.length, self.height) # THIS square's length and height
square1 = Square(2,2)
square2 = Square(4,4)
square1.print_length_and_height() # 2 2
square2.print_length_and_height() # 4 4
Now, this example is quite silly, of course, but i think it shows what SELF specifically is for: it refers to the particular instance of an object.
By all means, if you don't see the point to it, just do away with classes and just use functions, there nothing wrong with that.
You haven't utilised a class or object properly. Cutting out the garbage code, your program reduces to:
def test(x,y): #No class
return x+y
def test1(x,y): #No class
return x-y
print(example.test(10,5))
print(example.test1(10,5))
Output:
15
5
Your "class" is no more useful than if you wrapped your program in the nested structures:
if True:
for i in range(1):
...
A proper object will have attributes (data fields) and functions that operate on that data (see below). Your code has an empty object; hence, you have nothing on which to operate, no need for self, and no need for a class at all.
Rather, use a class when you need to encapsulate a data representation and associated operations. Below, I've reused some of your code to make example do some trivial complex number work. There are many extensions and improvements to make in this; I kept it relatively close to your original work.
class example(object):
def __init__(self, a, b):
self.a = a
self.b = b
def __repr__(self):
sign = ' + ' if self.b >= 0 else ' - '
return str(self.a) + sign + str(abs(self.b)) + 'i'
def add(self, x):
self.a += x.a
self.b += x.b
def sub(self, x):
self.a -= x.a
self.b -= x.b
complex1 = example(10, 5)
complex2 = example(-3, 2)
complex1.add(complex2)
print(complex1)
complex2.sub(complex1)
print(complex2)
Output:
7 + 7i
-10 - 5i
Are you familiar with Object-Oriented Paradigm?
If you don't you should check it. Python is a Object-Oriented Language and self lets you define your object properties.
An example:
You have a class named Vehicle. A vehicle could be a bike, a car, even a plane. So something you can include is a name and a type.
class Vehicle():
def init(self, name, type): # Constructor
self.name = name
self.type = type
def info(self):
print("I'm a ")
print(self.name)
That's all, now you have a vehicle with name and type. Every instance of Vehicle would have a name and a type different or not and every intance can access its own variables. I'm sorry I can't explain it better. Firstable you need to know Object-Oriented Paradigm knowledge. Please comment my answer if you have doubts & I'll answer you or give a link where it comes explained better.

Categories

Resources