Posts: 5
Threads: 2
Joined: Jun 2022
Jun-02-2022, 03:02 PM
(This post was last modified: Jun-02-2022, 09:38 PM by rufenghk.)
Hi, I'm a Python novice. I have the following code, but after running it doesn't return any result, not even error code, what is the problem?
def isIn(firstCorner=(1,2), secondCorner=(3,4), point=(1.5, 3.2)):
x1 , y1 = firstCorner
x2 , y2 = secondCorner
test1 , test2 = point
if (test1 >= x1 and test1 <= x2 and test2 >= y1 and test2 <= y2):
print('True')
elif (test1 >= x1 and test1 <= x2 and test2 <= y1 and test2 >= y2):
print('True')
elif (test1 <= x1 and test1 >= x2 and test2 >= y1 and test2 <= y2):
print('True')
elif (test1 <= x1 and test1 >= x2 and test2 <= y1 and test2 >= y2):
print('True')
else:
print('False') P.s. the code is for solving the following problem:
Write a function isIn() which returns boolean True if a point is within a rectangle specified by two sets of coordinates and boolean False if the point is outside the rectangle. The function should accept three parameters:
the first parameter is a set of coordinates which defines one of the corners of the rectangle,
the second parameter is also a set of coordinates that defines the second corner,
the third set of coordinates defines a single point which is being tested.
Gribouillis write Jun-02-2022, 03:37 PM:Please post all code, output and errors (in it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
Posts: 1,838
Threads: 2
Joined: Apr 2017
Jun-02-2022, 03:35 PM
(This post was last modified: Jun-02-2022, 03:38 PM by ndc85430.)
Please make sure you post code within "[python]" tags to preserve indentation and add syntax highlighting and line numbers.
First of all, your function isn't returning a boolean; all you're doing is printing 'True' or 'False' , so your function just returns None .
Secondly, you aren't calling the function anywhere.
Thirdly, why do you have default values for the arguments? Those seem a bit odd.
Posts: 1,583
Threads: 3
Joined: Mar 2020
It looks like you've defined a function. But it won't do anything unless you call the function elsewhere in your program.
Posts: 6,792
Threads: 20
Joined: Feb 2020
Jun-02-2022, 07:55 PM
(This post was last modified: Jun-02-2022, 07:55 PM by deanhystad.)
Though it is not unusual to provide default arguments for a function, I think here it indicates that you don't understand how functions work.
I would expect something that looks more like this:
def isIn(firstCorner, secondCorner, point):
x1, y1 = firstCorner
x2, y2 = secondCorner
test1, test2 = point
if test1 >= x1 and test1 <= x2 and test2 >= y1 and test2 <= y2:
print("True")
elif test1 >= x1 and test1 <= x2 and test2 <= y1 and test2 >= y2:
print("True")
elif test1 <= x1 and test1 >= x2 and test2 >= y1 and test2 <= y2:
print("True")
elif test1 <= x1 and test1 >= x2 and test2 <= y1 and test2 >= y2:
print("True")
else:
print("False")
isIn(firstCorner=(1, 2), secondCorner=(3, 4), point=(1.5, 3.2)) The argument values are provided by the function caller, not the function. Now you can reuse the function for any sized rectangle and any points.
This is not a very good function. You cannot use it to determine if point is actually in the (rectangular?) area defined by firstCorner, secondCorner. It would be more useful if "isIn" returned True/False instead of printing True/False.
def isIn(firstCorner, secondCorner, point):
x1, y1 = firstCorner
x2, y2 = secondCorner
test1, test2 = point
return x1 <= test1 <= x2 and y1 <= test2 <= y2
print(isIn(firstCorner=(1, 2), secondCorner=(3, 4), point=(1.5, 3.2))) Output: True
Now that the function returns a value you can print True or False, or you can use the returned value in an if statement, or as an argument to another function. The possibilities are endless.
isIn is a lousy function name. In what? What is in what? Some comments might be useful too.
def point_in_rectangle(lower_left, upper_right, point):
"""Return True if point is in rectangle defined by corners lowerLeft
and upper right.
"""
llx, lly = lower_left
urx, ury = upper_right
x, y = point
return llx <= x <= urx and lly <= y <= ury
print(point_in_rectangle((1, 2), (3, 4), (1.5, 3.2))) Now the code almost reads like a book. The function name describes what the function does. The argument names describes what the arguments mean. This function got a lot easier to use.
If you wanted to continue enhancing the code you could rewrite this as a class with attributes and methods. This code defines a Rectangle class with methods to return the rectangle area in addition to the contains method (replacement for isIn()).
from dataclasses import dataclass
@dataclass
class Rectangle:
"""A 2D rectangular shape defined by the lower left corner, width and height"""
x: float
y: float
width: float
height: float
def area(self):
"""Return area of rectangle"""
return self.width * self.height
def contains(self, point):
"""Return True if rectangle contains point"""
px, py = point
return (
self.x <= px <= self.x + self.width and self.y <= py <= self.y + self.height
)
myrect = Rectangle(1, 2, 2, 2)
for point in ((1.5, 3.2), (3, 7), (0, 3)):
print(
f"{myrect} Area = {myrect.area()} {'contains' if myrect.contains(point) else 'does not contain'} {point}"
) Output: Rectangle(x=1, y=2, width=2, height=2) Area = 4 contains (1.5, 3.2)
Rectangle(x=1, y=2, width=2, height=2) Area = 4 does not contain (3, 7)
Rectangle(x=1, y=2, width=2, height=2) Area = 4 does not contain (0, 3)
Posts: 5
Threads: 2
Joined: Jun 2022
Thanks very much everyone
Posts: 5
Threads: 2
Joined: Jun 2022
Jun-02-2022, 09:26 PM
(This post was last modified: Jun-04-2022, 10:15 PM by rufenghk.)
Thank you very much for your thorough answer, learned a lot.
But what your function didn't take into account is x1 isn't always less or equal to x2, the same goes for y1 and y2. But I guess I wasn't clear enough.;)
I wonder if Python will take compound statement like "return [(test1 >= x1 and test1 <= x2) or (test1 <= x1 and test1 >= x2)] and [(test2 >= y1 and test2 <= y2) or (test2 <= y1 and test2 >= y2)]"?
(Jun-02-2022, 07:55 PM)deanhystad Wrote: Though it is not unusual to provide default arguments for a function, I think here it indicates that you don't understand how functions work.
I would expect something that looks more like this:
def isIn(firstCorner, secondCorner, point):
x1, y1 = firstCorner
x2, y2 = secondCorner
test1, test2 = point
if test1 >= x1 and test1 <= x2 and test2 >= y1 and test2 <= y2:
print("True")
elif test1 >= x1 and test1 <= x2 and test2 <= y1 and test2 >= y2:
print("True")
elif test1 <= x1 and test1 >= x2 and test2 >= y1 and test2 <= y2:
print("True")
elif test1 <= x1 and test1 >= x2 and test2 <= y1 and test2 >= y2:
print("True")
else:
print("False")
isIn(firstCorner=(1, 2), secondCorner=(3, 4), point=(1.5, 3.2)) The argument values are provided by the function caller, not the function. Now you can reuse the function for any sized rectangle and any points.
This is not a very good function. You cannot use it to determine if point is actually in the (rectangular?) area defined by firstCorner, secondCorner. It would be more useful if "isIn" returned True/False instead of printing True/False.
def isIn(firstCorner, secondCorner, point):
x1, y1 = firstCorner
x2, y2 = secondCorner
test1, test2 = point
return x1 <= test1 <= x2 and y1 <= test2 <= y2
print(isIn(firstCorner=(1, 2), secondCorner=(3, 4), point=(1.5, 3.2))) Output: True
Now that the function returns a value you can print True or False, or you can use the returned value in an if statement, or as an argument to another function. The possibilities are endless.
isIn is a lousy function name. In what? What is in what? Some comments might be useful too.
def point_in_rectangle(lower_left, upper_right, point):
"""Return True if point is in rectangle defined by corners lowerLeft
and upper right.
"""
llx, lly = lower_left
urx, ury = upper_right
x, y = point
return llx <= x <= urx and lly <= y <= ury
print(point_in_rectangle((1, 2), (3, 4), (1.5, 3.2))) Now the code almost reads like a book. The function name describes what the function does. The argument names describes what the arguments mean. This function got a lot easier to use.
If you wanted to continue enhancing the code you could rewrite this as a class with attributes and methods. This code defines a Rectangle class with methods to return the rectangle area in addition to the contains method (replacement for isIn()).
from dataclasses import dataclass
@dataclass
class Rectangle:
"""A 2D rectangular shape defined by the lower left corner, width and height"""
x: float
y: float
width: float
height: float
def area(self):
"""Return area of rectangle"""
return self.width * self.height
def contains(self, point):
"""Return True if rectangle contains point"""
px, py = point
return (
self.x <= px <= self.x + self.width and self.y <= py <= self.y + self.height
)
myrect = Rectangle(1, 2, 2, 2)
for point in ((1.5, 3.2), (3, 7), (0, 3)):
print(
f"{myrect} Area = {myrect.area()} {'contains' if myrect.contains(point) else 'does not contain'} {point}"
) Output: Rectangle(x=1, y=2, width=2, height=2) Area = 4 contains (1.5, 3.2)
Rectangle(x=1, y=2, width=2, height=2) Area = 4 does not contain (3, 7)
Rectangle(x=1, y=2, width=2, height=2) Area = 4 does not contain (0, 3)
Posts: 6,792
Threads: 20
Joined: Feb 2020
Jun-03-2022, 12:31 AM
(This post was last modified: Jun-03-2022, 12:31 AM by deanhystad.)
If lower left is not always the lower left corner, make it so.
def point_in_rectangle(lower_left, upper_right, point):
"""Return True if point is in rectangle defined by corners lowerLeft
and upper right.
"""
llx = min(lower_left[0], upper_right[0])
lly = min(lower_left[1], upper_right[1])
urx = max(lower_left[0], upper_right[0])
ury = max(lower_left[1], upper_right[1])
x, y = point
return llx <= x <= urx and lly <= y <= ury But if you do that or not, use the Python way of comparing against a range, not the C way.
Do:
x1 <= test1 <= x2
Not
test1 >= x1 and test1 <= x2 If you really want to do a bunch of comparisons, do them using any():
def point_in_rectangle(lower_left, upper_right, point):
"""Return True if point is in rectangle defined by corners lowerLeft
and upper right.
"""
x1, y1 = lower_left
x2, y2 = upper_right
x, y = point
return any((
x1 <= x <= x2 and y1 <= y <= y2,
x1 <= x <= x2 and y1 >= y >= y2,
x1 >= x >= x2 and y1 <= y <= y2,
x1 >= x >= x2 and y1 >= y >= y2))
print(point_in_rectangle((1, 2), (3, 4), (1.5, 3.2))) See how easy it is to verify the logic when they are all aligned vertically like this?
Posts: 5
Threads: 2
Joined: Jun 2022
Thanks
(Jun-03-2022, 12:31 AM)deanhystad Wrote: If lower left is not always the lower left corner, make it so.
def point_in_rectangle(lower_left, upper_right, point):
"""Return True if point is in rectangle defined by corners lowerLeft
and upper right.
"""
llx = min(lower_left[0], upper_right[0])
lly = min(lower_left[1], upper_right[1])
urx = max(lower_left[0], upper_right[0])
ury = max(lower_left[1], upper_right[1])
x, y = point
return llx <= x <= urx and lly <= y <= ury But if you do that or not, use the Python way of comparing against a range, not the C way.
Do:
x1 <= test1 <= x2
Not
test1 >= x1 and test1 <= x2 If you really want to do a bunch of comparisons, do them using any():
def point_in_rectangle(lower_left, upper_right, point):
"""Return True if point is in rectangle defined by corners lowerLeft
and upper right.
"""
x1, y1 = lower_left
x2, y2 = upper_right
x, y = point
return any((
x1 <= x <= x2 and y1 <= y <= y2,
x1 <= x <= x2 and y1 >= y >= y2,
x1 >= x >= x2 and y1 <= y <= y2,
x1 >= x >= x2 and y1 >= y >= y2))
print(point_in_rectangle((1, 2), (3, 4), (1.5, 3.2))) See how easy it is to verify the logic when they are all aligned vertically like this?
|