-
Notifications
You must be signed in to change notification settings - Fork 1
add __repr__ for Board and Markers #86
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good not to call __str__
directly -- the string formatting will do that for us.
Requesting changes due to test failures.
robot/markers.py
Outdated
@@ -168,9 +168,12 @@ def spherical(self) -> SphericalCoord: | |||
""" | |||
return SphericalCoord(*self._raw_data['spherical']) | |||
|
|||
def __repr__(self): | |||
return "<robot.markers.{} >".format(self.__str__()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You shouldn't need to call __str__
explicitly here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in f6b302c
robot/board.py
Outdated
@@ -155,6 +155,9 @@ def close(self): | |||
""" | |||
self.socket.detach() | |||
|
|||
def __repr__(self): | |||
return "<{}>".format(self.__str__()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You shouldn't need to call __str__
explicitly here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in f6b302c
def __str__(self): | ||
bearing = self.spherical.rot_y_degrees | ||
return "<Marker {}: {:.0f}° {}, {:.2f}m away>".format( | ||
return "Marker {}: {:.0f}° {}, {:.2f}m away".format( | ||
self.id, | ||
abs(bearing), | ||
"right" if bearing > 0 else "left", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to specify "left" and "right" here if this is a bearing?
Also, I think clockwise and anti-clockwise might be more appropriate here as they are less ambiguous.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the issue here is that 'bearing' is the wrong variable name. I don't like mentioning clockwise or counter clockwise, as it's given without context here, and they might think it's the orientation of the marker
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
either way, this isn't changed in this PR and thus should be fixed separately
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think bearing
is probably fine here, if not 100% precise. The variable holds the bearing of the marker relative to the bearing of the camera. I feel using "left/right" to indicate "to the left/right of the camera" is acceptable here.
robot/markers.py
Outdated
@@ -168,9 +168,12 @@ def spherical(self) -> SphericalCoord: | |||
""" | |||
return SphericalCoord(*self._raw_data['spherical']) | |||
|
|||
def __repr__(self): | |||
return "<robot.markers.{} >".format(str(self)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think replacing robot.markers.
with nothing will lead to a nicer output. <Marker 1: ... m away>
looks quite nice
IMO Anyone know if there's a PEP for the recommended behaviour of |
@kierdavis I tend to agree, however in this case it would be a really long string. I believe the agreed method for this is to try for something which can be passed to |
From Python 3 docs: For many types, this function(__repr__) makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. |
One thing I do think should always happen though is the output of |
robot/board.py
Outdated
@@ -155,8 +155,11 @@ def close(self): | |||
""" | |||
self.socket.detach() | |||
|
|||
def __repr__(self): | |||
return "<{}>".format(str(self)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please drop redundant str
call here.
>>> class Foo:
... def __repr__(self):
... return 'repr'
... def __str__(self):
... return 'str'
...
>>> print('{}'.format(Foo()))
str
robot/markers.py
Outdated
@@ -168,9 +168,12 @@ def spherical(self) -> SphericalCoord: | |||
""" | |||
return SphericalCoord(*self._raw_data['spherical']) | |||
|
|||
def __repr__(self): | |||
return "<{}>".format(str(self)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please drop redundant str
call here (as above).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please re-review, have fixed the suggested changes (after 22 days lol)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes look ok, though the premise of this PR is wrong -- print(x)
calls __str__
not __repr__
:
In [1]: class Foo:
...: def __repr__(self):
...: return 'repr(Foo)'
...: def __str__(self):
...: return 'str(Foo)'
...:
In [2]: print(Foo())
str(Foo)
Note that the default __str__
calls __repr__
, which may have been the source of this confusion.
I would also rather that our __repr__
s behaved more like they're meant to. For the markers, I think having an abstract description is OK, though for the boards I think we should probably do something more accurate (see inline).
@@ -155,8 +155,11 @@ def close(self): | |||
""" | |||
self.socket.detach() | |||
|
|||
def __repr__(self): | |||
return "<{}>".format(self) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest that this be:
return '{}({!r})'.format(self.__class__.__name__, self.serial)
That would be truer repr
behaviour, though would admittedly rely on classes which take other construction parameters overriding the default.
If we do that, we can then drop the __str__
entirely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree, this would not be truer repr
behaviour. Please see my above comment and link to the Python 3 documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah. Apparently I meant self.socket_path
, not self.serial
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In which case we might want to keep the __str__
.
@Adimote was there a particular use-case or specific instance where you had seen a non-useful stringified board instance which this was trying to fix? If not, I suggest we shelve this until after the competition. |
Currently Board and Markers don't show pretty prints if you
print(markers)
. They do have__str__()
functions, butprint()
calls__repr__()
, so implement__repr__()