1

I have a few tests, and have written the code to check to see if the code works. I have two issues.

  1. I am not sure why 2 of my tests for checking if a Point is "contained" within a rectangle fail?
  2. Secondly, I have written a few tests, and code for whether two rectangles touch (or collide). I have nothing to check these with. I am not sure --> test(r.collision(Rectangle(Point(9, 4), 10, 5))) --> fails the test.
  3. Finally, for the "collision() and collides() code. I am not completes sure if they are correct?

Sorry for the extensive amount of code.

import sys


def test(did_pass):
    """ Print the rests of the test """
    linenum = sys._getframe(1).f_lineno  # gets the callers line number
    if did_pass:
        msg = "Test at line {} is ok.".format(linenum)
    else:
        msg = "Test at line {} FAILED.".format(linenum)
    print(msg)


class Point:
    """ Point class represents and manipulates x, y coordinates. """

    def __init__(self, x=0, y=0):
        """ Create a new point at x, y. """
        self.x = x
        self.y = y

    def __str__(self):
        """ Converting the point to a string. """
        return "({0}, {1})".format(self.x, self.y)


class Rectangle:
    """ A classes to manufacture rectangle objects """

    def __init__(self, posn, w, h):
        """ Initialise the rectange at posn, with width w, height h """
        self.corner = posn
        self.width = w
        self.height = h

    def __str__(self):
        return "({0}, {1}, {2})".format(self.corner, self.width, self.height)


    def contains(self, point):
        """ Test if a point falls with in the rectangle """
        outer_x = self.corner.x + self.width
        outer_y = self.corner.y + self.height
        return (self.corner.x <= point.x < outer_x and
                self.corner.y <= point.y < outer_y)

    def collision(self, other):
        """ Test if another rectangle collides with the first rectangle. """
        outer_x = self.corner.x + self.width
        outer_y = self.corner.y + self.height
        if (self.corner.x <= other.corner.x <= outer_x and
            self.corner.y <= other.corner.y <= outer_y):
            return True
        if (self.corner.x <= other.corner.x + other.width <= outer_x and
            self.corner.y <= other.corner.y + other.height <= outer_y):
            return True
        else:
            return False


def test_suite():
    r = Rectangle(Point(0, 0), 10, 5)

    test(r.contains(Point(0, 0)))
    test(r.contains(Point(3, 3)))
    test(not r.contains(Point(3, 7)))  # This fails. I'm not sure why?
    test(not r.contains(Point(3, 5)))  # This also fail. I'm not sure why?
    test(r.contains(Point(3, 4.99999)))
    test(not r.contains(Point(-3, -3)))

    # Testing if collision with the point of the Other Rectangle
    test(r.collision(Rectangle(Point(0, 0), 10, 5)))
    test(r.collision(Rectangle(Point(5, 0), 10, 5)))
    test(not r.collision(Rectangle(Point(10, 5), 10, 5)))
    test(r.collision(Rectangle(Point(9, 4), 10, 5)))  # This Code fails, I'm not sure why?
    test(not r.collision(Rectangle(Point(20, 5), 10, 5)))

    # Testing if collision with the top right corner of Other Rectangle
    test(not r.collision(Rectangle(Point(-11, 5), 10, 5)))
    test(r.collision(Rectangle(Point(0, 0), 10, 5)))
    test(not r.collision(Rectangle(Point(0, -6), 10, 5)))
    test(r.collision(Rectangle(Point(-9, -4), 10, 5)))


test_suite()

1 Answers1

0

Wrong Inequalities

Why does your contain function use strict inequalities only for the outer point ?

self.corner.x <= point.x < outer_x

You should decide whether the definition of "contain" means strictly inside, or counting anything exactly on the edges as well. Either use <= twice, or < for both sides.

Wrong Tests

Let's say that you decide to use <=.

Then this contains assertion is wrong, you should remove the not:

test(not r.contains(Point(3, 5)))

The point is on the edge of your rectangle, so it should count as contained in the rectangle:

This assertion is wrong too:

test(r.collision(Rectangle(Point(10, 5), 10, 5)))

Both rectangles are touching each other at coordinates (10,5) so you should remove the not.

If you were planning to go for the strict version of "contains", using <, then your first assertion is wrong because the point is only on the edge of your rectangle:

test(r.contains(Point(0, 0)))

Wrong Collision logic

Finally, your logic for rectangle is to simple, and wrong. Too bad you did not write enough tests to find this out !

You are simply checking if both (upper_left, lower_right) corner points are within your rectangle. Rectangle collision is not that simple. Maybe the rectangle passed in parameter is bigger and contains your rectangle ! In that case you won't be able to detect the collision.

I can refer you to another SO answer with illustrations on how to find rectangle intersections:

https://stackoverflow.com/a/25068722/4552193

Community
  • 1
  • 1
Nicomak
  • 2,319
  • 1
  • 21
  • 23
  • I appreciate the lengthy reply. I do understand your point with regard to the logic. The reason for using separate equalities for the Point test, was because it was required by the learning material I am using, and that was a test set. It states that "0 is included but 10 is excluded". The collision tests on the other hand are ones I made. This test --> test(not r.collision(Rectangle(Point(10, 5), 10, 5))) --> actually passed. It was the test --> test(r.collision(Rectangle(Point(9, 4), 10, 5))) --> which failed. This makes me think there is more wrong with my code? – Chase Frankenfeld Jun 24 '16 at 10:54
  • If you go to https://repl.it/languages/python3 and paste your code and click "Run", you will see that only `test(not r.collision(Rectangle(Point(10, 5), 10, 5)))` fails... – Nicomak Jul 08 '16 at 06:59
  • And that test fails because you used same inequalities for rectangle `collision()`, unlike your `contains()` function... You used `<= outer_x` and `<= outer_y` for rectangle collision but you expect them to fail when the value is strictly equal in your test. You use weird conventions and you got mixed up in them. – Nicomak Jul 08 '16 at 07:08