Last active
October 1, 2023 18:09
-
-
Save shrawanx/1df7365546a42664085d40877ecdd099 to your computer and use it in GitHub Desktop.
Python Program to implement Point, Line Segment, Ray and Line
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DEBUG = True | |
def input_and_exit_keys_handler( | |
msg="Enter your choice [or press c to exit]:" | |
) -> int: | |
if not msg.endswith(" "): | |
msg += " " | |
while True: | |
choice = input(msg) | |
if choice == "c": | |
exit(0) | |
try: | |
choice = int(choice) | |
except ValueError: | |
print("Invalid input. Enter a valid integer number") | |
continue | |
return choice | |
class Point: | |
def __init__(self, x: int, y: int, p=None, n=None, ptype="N"): | |
self.x = x | |
self.y = y | |
self.previous = p | |
self.next = n | |
self.ptype = ptype | |
def is_right_max(self): | |
if self.ptype == 'M': | |
return self.next is None | |
def is_left_max(self): | |
if self.ptype == 'M': | |
return self.previous is None | |
@staticmethod | |
def help_text(): | |
print(""" | |
Point: | |
1. Enter x and y coordinates | |
2. Press c to exit | |
""") | |
@classmethod | |
def get(cls, show_help=True, p=None, n=None, ptype="N"): | |
if show_help: | |
cls.help_text() | |
x = input_and_exit_keys_handler("Enter x: ") | |
y = input_and_exit_keys_handler("Enter y: ") | |
return cls(x, y, p, n, ptype=ptype) | |
def __str__(self): | |
return "Point: ({}, {})".format(self.x, self.y) | |
def show(self, **kwargs): | |
print("*" * 20) | |
print(self) | |
print("*" * 20) | |
class _LineBase: | |
def __init__(self, name: str, how_many_points: int, right_max=False, left_max=False): | |
self.name = name | |
self.how_many_points = how_many_points | |
self.right_max = right_max | |
self.left_max = left_max | |
self._points = [] | |
@classmethod | |
def setup(cls, name: str, how_many_points: int, right_max: bool, left_max: bool): | |
return cls(name, how_many_points, right_max, left_max) | |
@staticmethod | |
def is_collinear(point1: Point, point2: Point, point3: Point) -> bool: | |
area = abs(0.5 * ((point1.x * (point2.y - point3.y)) + | |
(point2.x * (point3.y - point1.y)) + | |
(point3.x * (point1.y - point2.y)))) | |
return area == 0 | |
def __str__(self): | |
return "{} Successfully created".format(self.name) | |
@staticmethod | |
def _last_point(points) -> Point: | |
for i in points: | |
if i.next is None: | |
return i | |
@staticmethod | |
def _first_point(points) -> Point: | |
for i in points: | |
if i.previous is None: | |
return i | |
def get(self): | |
for count in range(1, self.how_many_points + 1): | |
print("For Point({})".format(count)) | |
p = Point.get(show_help=False, | |
p=self._last_point(self._points) | |
) | |
if last := self._last_point(self._points): | |
last.next = p | |
self._points.append(p) | |
if self.right_max: | |
print("For Point{(Max)}" if not self.left_max else "For Point{(Right Max)}") | |
while True: | |
p = Point.get(show_help=False, | |
p=self._last_point(self._points), | |
ptype="M") | |
if not self.is_collinear(*self._points, p): | |
print("Point is not collinear with other points. Enter a valid point") | |
continue | |
break | |
if last := self._last_point(self._points): | |
last.next = p | |
self._points.append(p) | |
if self.left_max: | |
print("For Point{(Left Max)}") | |
while True: | |
p = Point.get(show_help=False, | |
n=self._first_point(self._points), | |
ptype="M") | |
if not self.is_collinear(*self._points[1:], p): | |
print("Point is not collinear with other points. Enter a valid point") | |
continue | |
break | |
if first := self._first_point(self._points): | |
first.previous = p | |
self._points.append(p) | |
return self | |
def show(self, debug): | |
print("*" * 20, end="\n") | |
print(self) | |
p = self._first_point(self._points) | |
while p: | |
if debug: | |
print("{} [Type: {}] [Previous: {}] [Next: {}]".format(p, p.ptype, p.previous, p.next)) | |
else: | |
print("{} [Type: {}]".format(p, p.ptype)) | |
p = p.next | |
print("*" * 20) | |
def main(): | |
print(""" | |
1. Point | |
2. Line Segment | |
3. Ray | |
4. Line | |
""") | |
mapping = { | |
1: Point, | |
2: _LineBase.setup("Line Segment", 2, right_max=False, left_max=False), | |
3: _LineBase.setup("Ray", 2, right_max=True, left_max=False), | |
4: _LineBase.setup("Line", 2, right_max=True, left_max=True) | |
} | |
while True: | |
choice = input_and_exit_keys_handler("Enter your choice [or press c to exit]:") | |
if choice in mapping.keys(): | |
klass = mapping[choice] | |
obj = klass.get() | |
obj.show(debug=DEBUG) | |
break | |
else: | |
_valid_choices = ",".join([str(k) for k in mapping.keys()]) | |
print("Valid Choices are: {}".format(_valid_choices)) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment