Repository: sympy/sympy
Pull request: Vertex and p_parameter for Parabolas declared symbolically
<!-- Your title above should be a short description of what
was changed. Do not include the issue number in the title. -->

#### References to other Issues or PRs
<!-- If this pull request fixes an issue, write "Fixes #NNNN" in that exact
format, e.g. "Fixes #1234". See
https://github.com/blog/1506-closing-issues-via-pull-requests . Please also
write a comment on that issue linking back to this pull request once it is
open. -->
Fixes #14461

#### Brief description of what is fixed or changed
Before, to define the sign of the `p_parameter`, a comparison between the focus points and the directrix coefficients was made. Now, the sign of the `p_parameter` is obtained using the `sign` function. 

#### Other comments


#### Release Notes

<!-- Write the release notes for this release below. See
https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more information
on how to write release notes. The bot will check your release notes
automatically to see if they are formatted correctly. -->

<!-- BEGIN RELEASE NOTES -->
* geometry
  * Fix `p_parameter` for Parabolas with symbolic variables
<!-- END RELEASE NOTES -->


Problem statement:
Parabola vertex can not be determined if Parabola is declared symbolically.
```
>>> from sympy import *
>>> a = symbols('a')
>>> l = Line((-a, 0), slope=oo)
>>> p = Parabola((a, 0), l)
>>> p.vertex
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "sympy/geometry/parabola.py", line 412, in vertex
    vertex = Point(focus.args[0] - self.p_parameter, focus.args[1])
  File "sympy/geometry/parabola.py", line 374, in p_parameter
    if (x < self.focus.args[0]):
  File "sympy/core/relational.py", line 229, in __nonzero__
    raise TypeError("cannot determine truth value of Relational")
TypeError: cannot determine truth value of Relational
```

Hints from issue discussion:

Commit message: include test and parentesis

Patch to review:
diff --git a/sympy/geometry/parabola.py b/sympy/geometry/parabola.py
index ac669102bcf0..8f4c08ed502e 100644
--- a/sympy/geometry/parabola.py
+++ b/sympy/geometry/parabola.py
@@ -14,7 +14,7 @@
 from sympy.geometry.point import Point, Point2D
 from sympy.geometry.line import Line, Line2D, Ray2D, Segment2D, LinearEntity3D
 from sympy.geometry.ellipse import Ellipse
-
+from sympy.functions import sign
 
 class Parabola(GeometrySet):
     """A parabolic GeometryEntity.
@@ -368,20 +368,13 @@ def p_parameter(self):
         -4
 
         """
-        if (self.axis_of_symmetry.slope == 0):
-            x = -(self.directrix.coefficients[2])
-            if (x < self.focus.args[0]):
-                p = self.focal_length
-            else:
-                p = -self.focal_length
+        if self.axis_of_symmetry.slope == 0:
+            x = self.directrix.coefficients[2]
+            p = sign(self.focus.args[0] + x)
         else:
-            y = -(self.directrix.coefficients[2])
-            if (y > self.focus.args[1]):
-                p = -self.focal_length
-            else:
-                p = self.focal_length
-
-        return p
+            y = self.directrix.coefficients[2]
+            p = sign(self.focus.args[1] + y)
+        return p * self.focal_length
 
     @property
     def vertex(self):
diff --git a/sympy/geometry/tests/test_parabola.py b/sympy/geometry/tests/test_parabola.py
index 21c832b65b00..fda6647bc2b0 100644
--- a/sympy/geometry/tests/test_parabola.py
+++ b/sympy/geometry/tests/test_parabola.py
@@ -1,18 +1,22 @@
 from sympy import Rational, oo, sqrt, S
 from sympy import Line, Point, Point2D, Parabola, Segment2D, Ray2D
-from sympy import Circle, Ellipse
+from sympy import Circle, Ellipse, symbols
 from sympy.utilities.pytest import raises
 
 
 def test_parabola_geom():
+    a, b = symbols('a b')
     p1 = Point(0, 0)
     p2 = Point(3, 7)
     p3 = Point(0, 4)
     p4 = Point(6, 0)
+    p5 = Point(a, a)
     d1 = Line(Point(4, 0), Point(4, 9))
     d2 = Line(Point(7, 6), Point(3, 6))
     d3 = Line(Point(4, 0), slope=oo)
     d4 = Line(Point(7, 6), slope=0)
+    d5 = Line(Point(b, a), slope=oo)
+    d6 = Line(Point(a, b), slope=0)
 
     half = Rational(1, 2)
 
@@ -25,6 +29,8 @@ def test_parabola_geom():
     pa7 = Parabola(p2, d1)
     pa8 = Parabola(p4, d1)
     pa9 = Parabola(p4, d3)
+    pa10 = Parabola(p5, d5)
+    pa11 = Parabola(p5, d6)
 
     raises(ValueError, lambda:
            Parabola(Point(7, 8, 9), Line(Point(6, 7), Point(7, 7))))
@@ -62,6 +68,9 @@ def test_parabola_geom():
     assert pa8.p_parameter == pa9.p_parameter
     assert pa8.vertex == pa9.vertex
     assert pa8.equation() == pa9.equation()
+    assert pa10.focal_length == sqrt((a - b) ** 2) / 2 # if a, b real == abs(a - b)/2
+    assert pa10.focal_length == pa11.focal_length
+    assert Point2D(*pa10.vertex[::-1]) == pa11.vertex # change axis x->y, y->x on pa10
 
 
 def test_parabola_intersection():


Code review comments:
diff_hunk: @@ -62,6 +68,9 @@ def test_parabola_geom():
     assert pa8.p_parameter == pa9.p_parameter
     assert pa8.vertex == pa9.vertex
     assert pa8.equation() == pa9.equation()
+    assert pa10.focal_length == sqrt((a - b) ** 2) / 2 # if a, b real == abs(a - b)/2
+    assert pa10.focal_length == pa11.focal_length
path: sympy/geometry/tests/test_parabola.py
text: @user1:
Or just `pa10.focal_length == pa11.focal_length == sqrt((a - b)**2)/2`.