0

My code:

def distance(a, b):
    ta = type(a)
    tb = type(b)
    if (ta == Vector and tb == Line):
        return ObjectRelations.point_to_line_distance(a, b)
    if (ta == Line and tb == Vector):
        return ObjectRelations.point_to_line_distance(b, a)

Is there a way to do both if comparisons in one? The order of arguments given to point_to_line_distance matters because of how my Vector and Line objects work. I want to check if either a or b is a Line and then check whether the other one is a Vector.

What would the best way to do this?

My way of doing it would work, but I just want to write clean code and my solution is not ideal.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
joppo
  • 1
  • 2
  • Welcome to Stack Overflow. Yes, but *it won't be any simpler*. Also, please read https://stackoverflow.com/questions/152580/whats-the-canonical-way-to-check-for-type-in-python. – Karl Knechtel Apr 12 '23 at 12:49
  • 1
    Store in a dict by type e.g. `d = { type(a):a, type(b):b }` and then simply return `ObjectRelations.point_to_line_distance(d[Vector], d[Line])`? I'm not sure it adds much, if anything, in terms of clarity or simplicity tbh. – jarmod Apr 12 '23 at 12:52

3 Answers3

4

If you are using Python 3.10 or newer you can use structural pattern matching to replace the if statements and explicit type checks:

def distance(a, b):
    match (a, b):
        case (Vector(), Line()):
            vector, line = a, b
        case (Line(), Vector()):
            line, vector = a, b
        case _:
            raise ValueError('Expected one Line and one Vector')
    return ObjectRelations.point_to_line_distance(vector, line)

See also: Convert multiple isinstance checks to structural pattern matching

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
3

First of all, proper way to check for type is by using isinstance - this way you also check for any potential subtypes.

Secondly, you can clean up that code by finding out which object is a Line, assigning it to designated variable, then checking if other is of a correct type and working on variables clear about their type.

def distance(a, b):
    if isinstance(a, Line):
        line = a
        vec = b
    elif isinstance(b, Line):
        line = b
        vec = a
    if not isinstance(vec, Vector):
        raise TypeError
    return ObjectRelations.point_to_line_distance(vec, line)
matszwecja
  • 6,357
  • 2
  • 10
  • 17
-2

You can use or to connect the two if statements. It would be

if (ta == Vector and tb == Line) or (ta == Line and tb == Vector):

Darkshadogt
  • 49
  • 1
  • 5