Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Need help solving a problem
#1
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.
Reply
#2
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.
Reply
#3
It looks like you've defined a function. But it won't do anything unless you call the function elsewhere in your program.
Reply
#4
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)
Reply
#5
Thanks very much everyone
Reply
#6
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)
Reply
#7
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?
Reply
#8
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?
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  SOlving LInear Equations in Python(Symoy, NUmpy) - Coefficient Problem quest 3 1,729 Jan-30-2022, 10:53 PM
Last Post: quest
  Problem in solving optimization problem Ruchika 0 1,548 Jul-27-2020, 05:28 AM
Last Post: Ruchika

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020