Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #33097 > unrolled thread
| Started by | Jennie <nameDOTportua@gmail.com> |
|---|---|
| First post | 2012-11-10 20:33 +0100 |
| Last post | 2012-11-11 16:32 -0800 |
| Articles | 20 on this page of 27 — 11 participants |
Back to article view | Back to comp.lang.python
Method default argument whose type is the class not yet defined Jennie <nameDOTportua@gmail.com> - 2012-11-10 20:33 +0100
Re: Method default argument whose type is the class not yet defined Chris Angelico <rosuav@gmail.com> - 2012-11-11 06:56 +1100
Re: Method default argument whose type is the class not yet defined Terry Reedy <tjreedy@udel.edu> - 2012-11-10 15:29 -0500
Re: Method default argument whose type is the class not yet defined Jennie <nameDOTportua@gmail.com> - 2012-11-10 21:51 +0100
Re: Method default argument whose type is the class not yet defined Dave Angel <d@davea.name> - 2012-11-10 17:30 -0500
Re: Method default argument whose type is the class not yet defined Jennie <marco.buttu@gmail.com> - 2012-11-10 21:51 +0100
Re: Method default argument whose type is the class not yet defined Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-11 01:13 +0000
Re: Method default argument whose type is the class not yet defined Chris Angelico <rosuav@gmail.com> - 2012-11-11 13:13 +1100
Re: Method default argument whose type is the class not yet defined Ian Kelly <ian.g.kelly@gmail.com> - 2012-11-10 19:43 -0700
Re: Method default argument whose type is the class not yet defined Roy Smith <roy@panix.com> - 2012-11-10 21:53 -0500
Re: Method default argument whose type is the class not yet defined Ian Kelly <ian.g.kelly@gmail.com> - 2012-11-10 23:43 -0700
Re: Method default argument whose type is the class not yet defined Ian Kelly <ian.g.kelly@gmail.com> - 2012-11-10 23:45 -0700
Re: Method default argument whose type is the class not yet defined Chris Angelico <rosuav@gmail.com> - 2012-11-11 13:47 +1100
Re: Method default argument whose type is the class not yet defined Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2012-11-11 14:21 +0000
Re: Method default argument whose type is the class not yet defined Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-11 22:31 +0000
Re: Method default argument whose type is the class not yet defined Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2012-11-12 00:31 +0000
Re: Method default argument whose type is the class not yet defined Steve Howell <showell30@yahoo.com> - 2012-11-11 16:56 -0800
Re: Method default argument whose type is the class not yet defined Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-12 04:46 +0000
Re: Method default argument whose type is the class not yet defined Mark Lawrence <breamoreboy@yahoo.co.uk> - 2012-11-12 01:10 +0000
Re: Method default argument whose type is the class not yet defined Roy Smith <roy@panix.com> - 2012-11-11 20:15 -0500
Re: Method default argument whose type is the class not yet defined Mark Lawrence <breamoreboy@yahoo.co.uk> - 2012-11-12 01:35 +0000
Re: Method default argument whose type is the class not yet defined Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2012-11-12 01:18 +0000
Re: Method default argument whose type is the class not yet defined Roy Smith <roy@panix.com> - 2012-11-11 20:34 -0500
Re: Method default argument whose type is the class not yet defined Mark Lawrence <breamoreboy@yahoo.co.uk> - 2012-11-12 01:29 +0000
Re: Method default argument whose type is the class not yet defined Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2012-11-12 01:50 +0000
Re: Method default argument whose type is the class not yet defined Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2012-11-11 01:23 +0000
Re: Method default argument whose type is the class not yet defined Steve Howell <showell30@yahoo.com> - 2012-11-11 16:32 -0800
Page 1 of 2 [1] 2 Next page →
| From | Jennie <nameDOTportua@gmail.com> |
|---|---|
| Date | 2012-11-10 20:33 +0100 |
| Subject | Method default argument whose type is the class not yet defined |
| Message-ID | <k7ma5c$qdk$1@speranza.aioe.org> |
What is the best solution to solve the following problem in Python 3.3? import math >>> class Point: ... def __init__(self, x=0, y=0): ... self.x = x ... self.y = y ... def __sub__(self, other): ... return Point(self.x - other.x, self.y - other.y) ... def distance(self, point=Point()): ... """Return the distance from `point`.""" ... return math.sqrt((self - point).x ** 2 + (self - point).y ** 2) ... Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 5, in Point NameError: name 'Point' is not defined I propose three solutions. The first one: >>> class Point: ... def __init__(self, x=0, y=0): ... self.x = x ... self.y = y ... def __sub__(self, other): ... return Point(self.x - other.x, self.y - other.y) ... def distance(self, point=None): ... p = point if point else Point() ... return math.sqrt((self - p).x ** 2 + (self - p).y ** 2) ... >>> p = Point() >>> p.distance() 0.0 >>> p.distance(Point(3, 4)) 5.0 The second one: >>> class Point: ... def __init__(self, x=0, y=0): ... self.x = x ... self.y = y ... def __sub__(self, other): ... return Point(self.x - other.x, self.y - other.y) ... >>> def distance(self, point=Point()): ... return math.sqrt((self - point).x ** 2 + (self - point).y ** 2) ... >>> Point.distance = distance >>> p = Point() >>> p.distance(Point(3, 4)) 5.0 The last one: >>> class Point: ... def __init__(self, x=0, y=0): ... self.x = x ... self.y = y ... Point.distance = distance ... def __sub__(self, other): ... return Point(self.x - other.x, self.y - other.y) ... >>> def distance(self, point=Point()): ... return math.sqrt((self - point).x ** 2 + (self - point).y ** 2) ... >>> p = Point() >>> p.distance(Point(3, 4)) 5.0 Is there a better solution? -- Jennie
[toc] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2012-11-11 06:56 +1100 |
| Message-ID | <mailman.3539.1352577386.27098.python-list@python.org> |
| In reply to | #33097 |
On Sun, Nov 11, 2012 at 6:33 AM, Jennie <nameDOTportua@gmail.com> wrote: > ... def distance(self, point=None): > ... p = point if point else Point() I'd go with this one. Definitely not the third one, which mutates the class according to a current global every time a Point is instantiated - could be *extremely* confusing if the name distance were ever rebound. You could also fiddle with the default args: >>> class Point: def __init__(self, x=0, y=0): self.x = x self.y = y def __sub__(self, other): return Point(self.x - other.x, self.y - other.y) def distance(self, point="Point()"): return math.sqrt((self - p).x ** 2 + (self - p).y ** 2) >>> Point.distance.__defaults__=Point(), # has to be a tuple ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2012-11-10 15:29 -0500 |
| Message-ID | <mailman.3541.1352579400.27098.python-list@python.org> |
| In reply to | #33097 |
On 11/10/2012 2:33 PM, Jennie wrote: > What is the best solution to solve the following problem in Python 3.3? > > import math > >>> class Point: > ... def __init__(self, x=0, y=0): > ... self.x = x > ... self.y = y > ... def __sub__(self, other): > ... return Point(self.x - other.x, self.y - other.y) > ... def distance(self, point=Point()): > ... """Return the distance from `point`.""" > ... return math.sqrt((self - point).x ** 2 + (self - point).y ** 2) > ... > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > File "<stdin>", line 5, in Point > NameError: name 'Point' is not defined > > I propose three solutions. The first one: > > >>> class Point: > ... def __init__(self, x=0, y=0): > ... self.x = x > ... self.y = y > ... def __sub__(self, other): > ... return Point(self.x - other.x, self.y - other.y) > ... def distance(self, point=None): > ... p = point if point else Point() > ... return math.sqrt((self - p).x ** 2 + (self - p).y ** 2) > ... > >>> p = Point() > >>> p.distance() > 0.0 > >>> p.distance(Point(3, 4)) > 5.0 What I do not like about this one is that it creates a new 0 point each time one is needed. Two solutions: change Point() to point0 in the distance function and create point0 = Point() after the class. -or- instead of p = line, px,py = point.x, point.y if point else 0.0, 0.0 > The second one: > > >>> class Point: > ... def __init__(self, x=0, y=0): > ... self.x = x > ... self.y = y > ... def __sub__(self, other): > ... return Point(self.x - other.x, self.y - other.y) > ... > >>> def distance(self, point=Point()): > ... return math.sqrt((self - point).x ** 2 + (self - point).y ** 2) > ... > >>> Point.distance = distance > >>> p = Point() > >>> p.distance(Point(3, 4)) > 5.0 my first thought > The last one: > > >>> class Point: > ... def __init__(self, x=0, y=0): > ... self.x = x > ... self.y = y > ... Point.distance = distance > ... def __sub__(self, other): > ... return Point(self.x - other.x, self.y - other.y) > ... > >>> def distance(self, point=Point()): > ... return math.sqrt((self - point).x ** 2 + (self - point).y ** 2) > ... > >>> p = Point() > >>> p.distance(Point(3, 4)) > 5.0 > > Is there a better solution? -- Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Jennie <nameDOTportua@gmail.com> |
|---|---|
| Date | 2012-11-10 21:51 +0100 |
| Message-ID | <509EBE5A.5080405@gmail.com> |
| In reply to | #33100 |
On 11/10/2012 09:29 PM, Terry Reedy wrote: > On 11/10/2012 2:33 PM, Jennie wrote: >> >> I propose three solutions. The first one: >> >> >>> class Point: >> ... def __init__(self, x=0, y=0): >> ... self.x = x >> ... self.y = y >> ... def __sub__(self, other): >> ... return Point(self.x - other.x, self.y - other.y) >> ... def distance(self, point=None): >> ... p = point if point else Point() >> ... return math.sqrt((self - p).x ** 2 + (self - p).y ** 2) > What I do not like about this one is that it creates a new 0 point each > time one is needed. Two solutions: > > change Point() to point0 in the distance function and create > point0 = Point() > after the class. > > -or- > instead of p = line, > px,py = point.x, point.y if point else 0.0, 0.0 Thanks, I like the second one :) -- Jennie
[toc] | [prev] | [next] | [standalone]
| From | Dave Angel <d@davea.name> |
|---|---|
| Date | 2012-11-10 17:30 -0500 |
| Message-ID | <mailman.3545.1352586645.27098.python-list@python.org> |
| In reply to | #33101 |
On 11/10/2012 03:51 PM, Jennie wrote: > On 11/10/2012 09:29 PM, Terry Reedy wrote: > >> On 11/10/2012 2:33 PM, Jennie wrote: >>> >>> I propose three solutions. The first one: >>> >>> >>> class Point: >>> ... def __init__(self, x=0, y=0): >>> ... self.x = x >>> ... self.y = y >>> ... def __sub__(self, other): >>> ... return Point(self.x - other.x, self.y - other.y) >>> ... def distance(self, point=None): >>> ... p = point if point else Point() >>> ... return math.sqrt((self - p).x ** 2 + (self - p).y ** 2) > >> What I do not like about this one is that it creates a new 0 point each >> time one is needed. Two solutions: >> >> change Point() to point0 in the distance function and create >> point0 = Point() >> after the class. >> >> -or- >> instead of p = line, >> px,py = point.x, point.y if point else 0.0, 0.0 > > Thanks, I like the second one :) > I like the first, once you fix the minor inefficiency in it; add the qualifier "is None" ... def distance(self, point=None): ... p = point if point is None else Point() ... return math.sqrt((self - p).x ** 2 + (self - p).y ** 2) The advantage it then has over the second one is that the whole class is defined inside the class. -- DaveA
[toc] | [prev] | [next] | [standalone]
| From | Jennie <marco.buttu@gmail.com> |
|---|---|
| Date | 2012-11-10 21:51 +0100 |
| Message-ID | <mailman.3542.1352580704.27098.python-list@python.org> |
| In reply to | #33100 |
On 11/10/2012 09:29 PM, Terry Reedy wrote: > On 11/10/2012 2:33 PM, Jennie wrote: >> >> I propose three solutions. The first one: >> >> >>> class Point: >> ... def __init__(self, x=0, y=0): >> ... self.x = x >> ... self.y = y >> ... def __sub__(self, other): >> ... return Point(self.x - other.x, self.y - other.y) >> ... def distance(self, point=None): >> ... p = point if point else Point() >> ... return math.sqrt((self - p).x ** 2 + (self - p).y ** 2) > What I do not like about this one is that it creates a new 0 point each > time one is needed. Two solutions: > > change Point() to point0 in the distance function and create > point0 = Point() > after the class. > > -or- > instead of p = line, > px,py = point.x, point.y if point else 0.0, 0.0 Thanks, I like the second one :) -- Jennie
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2012-11-11 01:13 +0000 |
| Message-ID | <509efbb6$0$29980$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #33097 |
On Sat, 10 Nov 2012 20:33:05 +0100, Jennie wrote:
[...]
> I propose three solutions. The first one:
>
> >>> class Point:
> ... def __init__(self, x=0, y=0):
> ... self.x = x
> ... self.y = y
> ... def __sub__(self, other):
> ... return Point(self.x - other.x, self.y - other.y)
Don't do this, because it breaks subclassing. Your instance should
dynamically get it's own class, not hard-code the name of Point.
return self.__class__(self.x - other.x, self.y - other.y)
That way, when you subclass Point, you can do arithmetic on the subclass
instances and they will do the Right Thing.
Note: Python's builtin numeric types don't do this, and it is a damned
nuisance:
py> class MyInt(int):
... pass
...
py> a, b = MyInt(23), MyInt(42)
py> assert type(a) is MyInt and type(b) is MyInt
py> type(a + b)
<type 'int'>
Back to your class:
> ... def distance(self, point=None):
> ... p = point if point else Point()
> ... return math.sqrt((self - p).x ** 2 + (self - p).y ** 2)
Almost but not quite. I assume that, in a full Point class, you would
want Point(0, 0) to count as false in a boolean context. (A "falsey"
value, like None, [], 0.0, etc.) So change the test to an explicit test
for None, not just any falsey value:
if point is None:
point = self.__class__() # Allow subclassing to work.
> The second one:
>
> >>> class Point:
> ... def __init__(self, x=0, y=0):
> ... self.x = x
> ... self.y = y
> ... def __sub__(self, other):
> ... return Point(self.x - other.x, self.y - other.y)
> ...
> >>> def distance(self, point=Point()):
> ... return math.sqrt((self - point).x ** 2 + (self - point).y ** 2)
> ...
> >>> Point.distance = distance
Cute, but ugly and messy. You can inject methods into a class, of course,
but that's an awfully big hammer to crack this tiny little nut. Your
first solution is better.
Here is a variation which, according to your tastes, may count as more or
less ugly: inject the default value into the method:
class Point:
def distance(self, other=None): # None is a placeholder
delta = self - other
return math.sqrt(delta.x ** 2 + delta.y ** 2)
Point.distance.__defaults__ = (Point(),)
# In Python 2, use:
# Point.distance.__func__.func_defaults = (Point(),)
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2012-11-11 13:13 +1100 |
| Message-ID | <mailman.3548.1352600034.27098.python-list@python.org> |
| In reply to | #33110 |
On Sun, Nov 11, 2012 at 12:13 PM, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > Almost but not quite. I assume that, in a full Point class, you would > want Point(0, 0) to count as false in a boolean context. (A "falsey" > value, like None, [], 0.0, etc.) I would not assume that. The origin is a point, just like any other. With a Line class, you could deem a zero-length line to be like a zero-element list, but Point(0,0) is more like the tuple (0,0) which is definitely True. In any case, this would not even matter, beyond unnecessary work; the bug would occur only if you seek the distance to Point(0,0), at which point[1] the code would throw out the incoming Point and go with the default of 0,0. So it'd result in the same distance. ChrisA [1] Sorry, couldn't resist
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2012-11-10 19:43 -0700 |
| Message-ID | <mailman.3549.1352601828.27098.python-list@python.org> |
| In reply to | #33110 |
On Sat, Nov 10, 2012 at 7:13 PM, Chris Angelico <rosuav@gmail.com> wrote: > I would not assume that. The origin is a point, just like any other. > With a Line class, you could deem a zero-length line to be like a > zero-element list, but Point(0,0) is more like the tuple (0,0) which > is definitely True. It's more like the number 0 than the tuple (0,0). 0 is the origin on a 1-dimensional number line. (0,0) is the origin on a 2-dimensional number plane. In fact, it might be pointed out that Point(0, 0) is a generalization of 0+0j, which is equal to 0.
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2012-11-10 21:53 -0500 |
| Message-ID | <roy-2CDC35.21534210112012@news.panix.com> |
| In reply to | #33113 |
In article <mailman.3549.1352601828.27098.python-list@python.org>, Ian Kelly <ian.g.kelly@gmail.com> wrote: > On Sat, Nov 10, 2012 at 7:13 PM, Chris Angelico <rosuav@gmail.com> wrote: > > I would not assume that. The origin is a point, just like any other. > > With a Line class, you could deem a zero-length line to be like a > > zero-element list, but Point(0,0) is more like the tuple (0,0) which > > is definitely True. > > It's more like the number 0 than the tuple (0,0). > > 0 is the origin on a 1-dimensional number line. > (0,0) is the origin on a 2-dimensional number plane. > In fact, it might be pointed out that Point(0, 0) is a generalization > of 0+0j, which is equal to 0. If (0,0) is the origin on a plane, then (0,) should be the origin on a line. If you consider 0 + 0j to be the origin of a plane, then 0 is the origin of a line. Either way is plausible, but you need to be consistent.
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2012-11-10 23:43 -0700 |
| Message-ID | <mailman.3551.1352616258.27098.python-list@python.org> |
| In reply to | #33115 |
On Sat, Nov 10, 2012 at 7:53 PM, Roy Smith <roy@panix.com> wrote: > In article <mailman.3549.1352601828.27098.python-list@python.org>, > Ian Kelly <ian.g.kelly@gmail.com> wrote: > >> On Sat, Nov 10, 2012 at 7:13 PM, Chris Angelico <rosuav@gmail.com> wrote: >> > I would not assume that. The origin is a point, just like any other. >> > With a Line class, you could deem a zero-length line to be like a >> > zero-element list, but Point(0,0) is more like the tuple (0,0) which >> > is definitely True. >> >> It's more like the number 0 than the tuple (0,0). >> >> 0 is the origin on a 1-dimensional number line. >> (0,0) is the origin on a 2-dimensional number plane. > >> In fact, it might be pointed out that Point(0, 0) is a generalization >> of 0+0j, which is equal to 0. > > > If (0,0) is the origin on a plane, then (0,) should be the origin on a > line. If you consider 0 + 0j to be the origin of a plane, then 0 is the > origin of a line. Either way is plausible, but you need to be > consistent. Where I wrote "(0,0) is the origin" above I was not referring to a point, not a tuple, but I can see how that was confusing.
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2012-11-10 23:45 -0700 |
| Message-ID | <mailman.3552.1352616377.27098.python-list@python.org> |
| In reply to | #33115 |
On Sat, Nov 10, 2012 at 11:43 PM, Ian Kelly <ian.g.kelly@gmail.com> wrote: > Where I wrote "(0,0) is the origin" above I was not referring to a > point, not a tuple, but I can see how that was confusing. What I meant to say is I *was* referring to a point. Gah!
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2012-11-11 13:47 +1100 |
| Message-ID | <mailman.3550.1352602070.27098.python-list@python.org> |
| In reply to | #33110 |
On Sun, Nov 11, 2012 at 1:43 PM, Ian Kelly <ian.g.kelly@gmail.com> wrote: > On Sat, Nov 10, 2012 at 7:13 PM, Chris Angelico <rosuav@gmail.com> wrote: >> I would not assume that. The origin is a point, just like any other. >> With a Line class, you could deem a zero-length line to be like a >> zero-element list, but Point(0,0) is more like the tuple (0,0) which >> is definitely True. > > It's more like the number 0 than the tuple (0,0). > > 0 is the origin on a 1-dimensional number line. > (0,0) is the origin on a 2-dimensional number plane. > > In fact, it might be pointed out that Point(0, 0) is a generalization > of 0+0j, which is equal to 0. Ah, good point. In any case, though, it'd be an utterly inconsequential bug. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Oscar Benjamin <oscar.j.benjamin@gmail.com> |
|---|---|
| Date | 2012-11-11 14:21 +0000 |
| Message-ID | <mailman.3559.1352643681.27098.python-list@python.org> |
| In reply to | #33110 |
On 11 November 2012 02:47, Chris Angelico <rosuav@gmail.com> wrote: > On Sun, Nov 11, 2012 at 1:43 PM, Ian Kelly <ian.g.kelly@gmail.com> wrote: >> On Sat, Nov 10, 2012 at 7:13 PM, Chris Angelico <rosuav@gmail.com> wrote: >>> I would not assume that. The origin is a point, just like any other. >>> With a Line class, you could deem a zero-length line to be like a >>> zero-element list, but Point(0,0) is more like the tuple (0,0) which >>> is definitely True. >> >> It's more like the number 0 than the tuple (0,0). >> >> 0 is the origin on a 1-dimensional number line. >> (0,0) is the origin on a 2-dimensional number plane. >> >> In fact, it might be pointed out that Point(0, 0) is a generalization >> of 0+0j, which is equal to 0. > > Ah, good point. In any case, though, it'd be an utterly inconsequential bug. You were right the first time, Chris. A point that happens to coincide with the arbitrarily chosen origin is no more truthy or falsey than any other. A vector of length 0 on the other hand is a very different beast. The significance of zero in real algebra is not that it is the origin but rather that it is the additive and multiplicative zero: a + 0 = a for any real number a a * 0 = 0 for any real number a The same is true for a vector v0, of length 0: v + v0 = v for any vector v a * v0 = v0 for any scalar a There is however no meaningful sense in which points (as opposed to vectors) can be added to each other or multiplied by anything, so there is no zero point. The relationship between points and vectors is analogous to the relationship between datetimes and timedeltas. Having Vector(0, 0) evaluate to False is analogous to having timedelta(0) evaluate to False and is entirely sensible. Having Point(0, 0) evaluate to False is precisely the same conceptual folly that sees midnight evaluate as False. Oscar
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2012-11-11 22:31 +0000 |
| Message-ID | <50a0272d$0$21756$c3e8da3$76491128@news.astraweb.com> |
| In reply to | #33128 |
On Sun, 11 Nov 2012 14:21:19 +0000, Oscar Benjamin wrote:
> On 11 November 2012 02:47, Chris Angelico <rosuav@gmail.com> wrote:
>> On Sun, Nov 11, 2012 at 1:43 PM, Ian Kelly <ian.g.kelly@gmail.com>
>> wrote:
>>> On Sat, Nov 10, 2012 at 7:13 PM, Chris Angelico <rosuav@gmail.com>
>>> wrote:
>>>> I would not assume that. The origin is a point, just like any other.
>>>> With a Line class, you could deem a zero-length line to be like a
>>>> zero-element list, but Point(0,0) is more like the tuple (0,0) which
>>>> is definitely True.
Don't conflate the set of all tuples of arbitrary length with points,
which have fixed length. Points are not *sequences* -- in Python, we
treat tuples as sequences first and records second, because that is a
useful thing to do. (But it is not the only useful thing to do: if we
treated them as records first and sequences second, we might want to say
that a tuple t was falsey if all the fields in t were falsey.)
In the case of a Point class, a Point is definitely not a sequence. That
we put the x-coordinate first and the y-coordinate second is a mere
convention, like writing left to right. The mathematical properties of
points do not depend on the x-coordinate coming first. Since points
should not be treated as sequences, the requirement that non-empty
sequences be treated as truthy is irrelevant.
>>> It's more like the number 0 than the tuple (0,0).
>>>
>>> 0 is the origin on a 1-dimensional number line. (0,0) is the origin on
>>> a 2-dimensional number plane.
>>>
>>> In fact, it might be pointed out that Point(0, 0) is a generalization
>>> of 0+0j, which is equal to 0.
>>
>> Ah, good point. In any case, though, it'd be an utterly inconsequential
>> bug.
>
> You were right the first time, Chris. A point that happens to coincide
> with the arbitrarily chosen origin is no more truthy or falsey than any
> other. A vector of length 0 on the other hand is a very different beast.
Nonsense. The length and direction of a vector is relative to the origin.
If the origin is arbitrary, as you claim, then so is the length of the
vector.
Just because we can perform vector transformations on the plane to move
the origin to some point other that (0,0) doesn't make (0,0) an
"arbitrarily chosen origin". It is no more arbitrary than 0 as the origin
of the real number line.
And yes, we can perform 1D vector transformations on the real number line
too. Here's a version of range that sets the origin to 42, not 0:
def myrange(start, end=None, step=1):
if end is None:
start = 42
return range(start, end, step)
Nevertheless, there really is something special about the point 0 on the
real number line, the point (0,0) on the complex number plane, the point
(0,0,0) in the 3D space, (0,0,0,0) in 4D space, etc. It is not just an
arbitrary convention that we set the origin to 0.
In other words: to the extent that your arguments that zero-vectors are
special are correct, the same applies to zero-points, since vectors are
defined as a magnitude and direction *from the origin*.
To put it yet another way:
The complex number a+bj is equivalent to the 2D point (a, b) which is
equivalent to the 2D vector [a, b]. If (0, 0) shouldn't be considered
falsey, neither should [0, 0].
> The significance of zero in real algebra is not that it is the origin
> but rather that it is the additive and multiplicative zero:
>
> a + 0 = a for any real number a
> a * 0 = 0 for any real number a
I'm not sure what you mean by "additive and multiplicative zero", you
appear to be conflating two different properties here. 0 is the additive
*identity*, but 1 is the multiplicative identity:
a + 0 = a
a * 1 = a
for any real number a.
If the RHS must be zero, then there is a unique multiplicative zero, but
no unique additive zero:
a * 0 = 0 for any real number a
a + -a = 0 for any real number a
> The same is true for a vector v0, of length 0:
>
> v + v0 = v for any vector v
> a * v0 = v0 for any scalar a
Well that's a bogus analogy. Since you're talking about the domain of
vectors, the relevant identify for the second line should be:
v * v0 = v0 for any vector v
except that doesn't work, since vector algebra doesn't define a vector
multiplication operator.[1] It does define multiplication between a
vector and a scalar, which represents a scale transformation.
> There is however no meaningful sense in which points (as opposed to
> vectors) can be added to each other or multiplied by anything, so there
> is no zero point.
I think that the great mathematician Carl Gauss would have something to
say about that.
Points in the plane are equivalent to complex numbers, and you can
certainly add and multiply complex numbers. Adding two points is
equivalent to a translation; multiplication of a scalar with a point is
equivalent to a scale transformation. Multiplying two points is
equivalent to complex multiplication, which is a scale + a rotation.
Oh look, that's exactly the same geometric interpretation as for vectors.
Hardly surprising, since vectors are the magnitude and direction of a
line from the origin to a point.
> The relationship between points and vectors is analogous to the
> relationship between datetimes and timedeltas. Having Vector(0, 0)
> evaluate to False is analogous to having timedelta(0) evaluate to False
> and is entirely sensible. Having Point(0, 0) evaluate to False is
> precisely the same conceptual folly that sees midnight evaluate as
> False.
If you are dealing with datetimes, then "midnight 2012-11-12" is not
falsey. The only falsey datetime is the zero datetime. Since it would be
awfully inconvenient to start counting times from the Big Bang, we pick
an arbitrary zero point, the Epoch, which in Unix systems is midnight 1
January 1970, and according to the logic of Unix system administrators,
that is so far in the distant past that it might as well be the Big Bang.
(People with more demanding requirements don't use Unix or Windows
timestamps for recording date times. E.g. astronomers use the Julian
system, not to be confused with the Julian calendar.)
The midnight problem only occurs when you deal with *times* on their own,
not datetimes, in which case the relationship with timedeltas is not
defined. How far apart is 1:00am and 2:00am? Well, it depends, doesn't
it? It could be 1 hour, 25 hours, 49 hours, ...
In any case, since times are modulo 24 hours, they aren't really relevant
to what we are discussing.
[1] There is no single meaningful definition of vector multiplication
that works for all dimensions. In two dimensions, you can define the dot
product of two vectors to give a scalar; in three dimensions you have a
dot product and a vector product.
Since vectors are equivalent to points, and points are equivalent to
complex numbers, one could define a vector operation equivalent to
complex multiplication. There is a natural geometric interpretation of
this multiplication: it is a scaling + rotation.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Oscar Benjamin <oscar.j.benjamin@gmail.com> |
|---|---|
| Date | 2012-11-12 00:31 +0000 |
| Message-ID | <mailman.3568.1352680316.27098.python-list@python.org> |
| In reply to | #33144 |
On 11 November 2012 22:31, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > On Sun, 11 Nov 2012 14:21:19 +0000, Oscar Benjamin wrote: > >> On 11 November 2012 02:47, Chris Angelico <rosuav@gmail.com> wrote: >>> On Sun, Nov 11, 2012 at 1:43 PM, Ian Kelly <ian.g.kelly@gmail.com> >>> wrote: >>>> On Sat, Nov 10, 2012 at 7:13 PM, Chris Angelico <rosuav@gmail.com> >>>> wrote: >>>>> I would not assume that. The origin is a point, just like any other. >>>>> With a Line class, you could deem a zero-length line to be like a >>>>> zero-element list, but Point(0,0) is more like the tuple (0,0) which >>>>> is definitely True. >>>> It's more like the number 0 than the tuple (0,0). >>>> >>>> 0 is the origin on a 1-dimensional number line. (0,0) is the origin on >>>> a 2-dimensional number plane. >>>> >>>> In fact, it might be pointed out that Point(0, 0) is a generalization >>>> of 0+0j, which is equal to 0. >>> >>> Ah, good point. In any case, though, it'd be an utterly inconsequential >>> bug. >> >> You were right the first time, Chris. A point that happens to coincide >> with the arbitrarily chosen origin is no more truthy or falsey than any >> other. A vector of length 0 on the other hand is a very different beast. > > Nonsense. The length and direction of a vector is relative to the origin. > If the origin is arbitrary, as you claim, then so is the length of the > vector. Wrong on all counts. Neither the length not the direction os a vector are relative to any origin. When we choose to express a vector in Cartesian components our representation assumes an orientation for the axes of the coordinate system. Even in this sense, though, the origin itself does not affect the components of the vector. I have spent a fair few hours in the past few weeks persuading teenaged Engineering students to maintain a clear distinction between points, vectors and lines. One of the ways that I distinguish vectors from points is to say that a vector is like an arrow but its base has no particular position. A point on the other hand is quite simply a position. Given an origin (an arbitrarily chosen point) we can specify another point using a "position vector": a vector from the origin to the point in question. > Just because we can perform vector transformations on the plane to move > the origin to some point other that (0,0) doesn't make (0,0) an > "arbitrarily chosen origin". It is no more arbitrary than 0 as the origin > of the real number line. (0, 0) are the coordinates of the origin *relative to itself*. Had we chosen a different origin, the point that was previously called (0, 0) would now be called (a, b) for some other numbers a and b. > And yes, we can perform 1D vector transformations on the real number line > too. Here's a version of range that sets the origin to 42, not 0: > > def myrange(start, end=None, step=1): > if end is None: > start = 42 > return range(start, end, step) This is lost on me... > Nevertheless, there really is something special about the point 0 on the > real number line Agreed. > , the point (0,0) on the complex number plane, Also agreed. > the point > (0,0,0) in the 3D space, (0,0,0,0) in 4D space, etc. It is not just an > arbitrary convention that we set the origin to 0. Wrong. The point (0,0,0,...) in some ND space is an arbitrarily chosen position. By this I don't mean to say that the sequence of coordinates consisting of all zeros is arbitrary. The choice of the point *in the real/hypothetical space* that is designated by the sequence of zero coordinates is arbitrary. > In other words: to the extent that your arguments that zero-vectors are > special are correct, the same applies to zero-points, since vectors are > defined as a magnitude and direction *from the origin*. Plain wrong. Vectors are not defined *from any origin*. > To put it yet another way: > > The complex number a+bj is equivalent to the 2D point (a, b) which is > equivalent to the 2D vector [a, b]. If (0, 0) shouldn't be considered > falsey, neither should [0, 0]. a+bj is not equivalent to the 2D point (a, b). It is possible to define a mapping between complex numbers and a 2D space so that a+bj corresponds to the point (a, b) *under that map*. However there are an infinite number of such possible mappings between the two spaces including a+bj -> (a+1, b+1). >> The significance of zero in real algebra is not that it is the origin >> but rather that it is the additive and multiplicative zero: >> >> a + 0 = a for any real number a >> a * 0 = 0 for any real number a > > I'm not sure what you mean by "additive and multiplicative zero", you > appear to be conflating two different properties here. 0 is the additive > *identity*, but 1 is the multiplicative identity: I mean that it has the properties that zero has when used in addition and multiplication: http://en.wikipedia.org/wiki/0_%28number%29#Elementary_algebra > > a + 0 = a > a * 1 = a > for any real number a. No. I meant the two properties that I listed. > > If the RHS must be zero, then there is a unique multiplicative zero, but > no unique additive zero: > > a * 0 = 0 for any real number a > a + -a = 0 for any real number a That is not the same as: a + 0 = a >> The same is true for a vector v0, of length 0: >> >> v + v0 = v for any vector v >> a * v0 = v0 for any scalar a > > Well that's a bogus analogy. Since you're talking about the domain of > vectors, the relevant identify for the second line should be: > > v * v0 = v0 for any vector v > > except that doesn't work, since vector algebra doesn't define a vector > multiplication operator.[1] It does define multiplication between a > vector and a scalar, which represents a scale transformation. That is precisely the multiplication operation that I was referring to. There are other senses of vector multiplication between vectors for which v0 will also behave as a "zero" under multiplication: v . v0 = 0 for any vector v v x v0 = 0 for any vector v >> There is however no meaningful sense in which points (as opposed to >> vectors) can be added to each other or multiplied by anything, so there >> is no zero point. > > I think that the great mathematician Carl Gauss would have something to > say about that. Is the text below a quote? > Points in the plane are equivalent to complex numbers, and you can > certainly add and multiply complex numbers. Adding two points is > equivalent to a translation; multiplication of a scalar with a point is > equivalent to a scale transformation. Multiplying two points is > equivalent to complex multiplication, which is a scale + a rotation. The last point is bizarre. Complex multiplication makes no sense when you're trying to think about vectors. Draw a 2D plot and convince yourself that the square of the point (0, 1) is (-1, 0). > Oh look, that's exactly the same geometric interpretation as for vectors. > Hardly surprising, since vectors are the magnitude and direction of a > line from the origin to a point. Here it becomes clear that you have conflated "position vectors" with vectors in general. Let me list some other examples of vectors that are clearly not "from the origin to a point": velocity acceleration force electric field angular momentum wave vector (I could go on) >> The relationship between points and vectors is analogous to the >> relationship between datetimes and timedeltas. Having Vector(0, 0) >> evaluate to False is analogous to having timedelta(0) evaluate to False >> and is entirely sensible. Having Point(0, 0) evaluate to False is >> precisely the same conceptual folly that sees midnight evaluate as >> False. > > If you are dealing with datetimes, then "midnight 2012-11-12" is not > falsey. The only falsey datetime is the zero datetime. Since it would be > awfully inconvenient to start counting times from the Big Bang, we pick > an arbitrary zero point, the Epoch, which in Unix systems is midnight 1 > January 1970, and according to the logic of Unix system administrators, > that is so far in the distant past that it might as well be the Big Bang. > > (People with more demanding requirements don't use Unix or Windows > timestamps for recording date times. E.g. astronomers use the Julian > system, not to be confused with the Julian calendar.) > > The midnight problem only occurs when you deal with *times* on their own, > not datetimes, in which case the relationship with timedeltas is not > defined. How far apart is 1:00am and 2:00am? Well, it depends, doesn't > it? It could be 1 hour, 25 hours, 49 hours, ... > > In any case, since times are modulo 24 hours, they aren't really relevant > to what we are discussing. They are relevant. The point is that conflating points and vectors is the same as conflating datetime and timedelta objects. The zero of datetime.timedelta objects is not arbitrary but the zero of datetime.time objects is. > Since vectors are equivalent to points, and points are equivalent to > complex numbers, one could define a vector operation equivalent to > complex multiplication. There is a natural geometric interpretation of > this multiplication: it is a scaling + rotation. Vectors, points and complex numbers are not equivalent. There are cases in which it is reasonable to think of them as equivalent for a particular purpose. That does not diminish the fundamental differences between them. Oscar
[toc] | [prev] | [next] | [standalone]
| From | Steve Howell <showell30@yahoo.com> |
|---|---|
| Date | 2012-11-11 16:56 -0800 |
| Message-ID | <cd9984c9-1e82-4e76-88e5-eeaa69a78955@qi10g2000pbb.googlegroups.com> |
| In reply to | #33154 |
On Nov 11, 4:31 pm, Oscar Benjamin <oscar.j.benja...@gmail.com> wrote: > On 11 November 2012 22:31, Steven D'Aprano > > Nonsense. The length and direction of a vector is relative to the origin. > > If the origin is arbitrary, as you claim, then so is the length of the > > vector. > > Wrong on all counts. Neither the length not the direction os a vector > are relative to any origin. When we choose to express a vector in > Cartesian components our representation assumes an orientation for the > axes of the coordinate system. Even in this sense, though, the origin > itself does not affect the components of the vector. > Thank you for pushing back on Steven's imprecise statement that the "direction of a vector is relative to the origin." You can't find an angle between two points. That's absurd. You need axes for context. > Vectors, points and complex numbers are not equivalent. There are > cases in which it is reasonable to think of them as equivalent for a > particular purpose. That does not diminish the fundamental differences > between them. > I looked to wikipedia for clarity, but the definition of a Euclidean vector is somewhat muddy: http://en.wikipedia.org/wiki/Euclidean_vector They say that the formal definition of a vector is a directed line segment. But then they define a "free vector" as an entity where only the magnitude and direction matter, not the initial point. As you say, it's not unreasonable to treat vectors, points, and complex numbers as equivalent in many circumstances. But, if you're gonna be pedantic, they really are different things.
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2012-11-12 04:46 +0000 |
| Message-ID | <50a07f22$0$21742$c3e8da3$76491128@news.astraweb.com> |
| In reply to | #33154 |
On Mon, 12 Nov 2012 00:31:53 +0000, Oscar Benjamin wrote: [...] >>> You were right the first time, Chris. A point that happens to coincide >>> with the arbitrarily chosen origin is no more truthy or falsey than >>> any other. A vector of length 0 on the other hand is a very different >>> beast. >> >> Nonsense. The length and direction of a vector is relative to the >> origin. If the origin is arbitrary, as you claim, then so is the length >> of the vector. > > Wrong on all counts. Neither the length not the direction os a vector > are relative to any origin. When we choose to express a vector in > Cartesian components our representation assumes an orientation for the > axes of the coordinate system. Even in this sense, though, the origin > itself does not affect the components of the vector. Draw a set of axes and mark the vector [1, 1]. Here's a crappy ASCII art diagram, with X marking the head of the vector and a line drawn from the origin to the head. | | X | / | / |/ +------ Now draw a second set of axes with the origin set at the head of that vector. For reference, I leave the previous axis in place. As before, X represents the head of the vector. | | ----X----- | | | | | | +---|-- Note that the "body" of the vector -- the line from the origin to the head -- is gone. That's because the vector [1, 1] is transformed to the vector [0, 0] under a translation of one unit in both the X and Y directions. The magnitude of the vector under one coordinate system is 1, under the second it is 0. In a nutshell, you can't talk about either *distance* (magnitude) or *direction* without an answer to "distance from where? direction relative to what?". > I have spent a fair few hours in the past few weeks persuading teenaged > Engineering students to maintain a clear distinction between points, > vectors and lines. One of the ways that I distinguish vectors from > points is to say that a vector is like an arrow but its base has no > particular position. A point on the other hand is quite simply a > position. Given an origin (an arbitrarily chosen point) we can specify > another point using a "position vector": a vector from the origin to the > point in question. Just because you have spent a lot of time and effort giving people advice doesn't make it *good* advice. [...] > Wrong. The point (0,0,0,...) in some ND space is an arbitrarily chosen > position. By this I don't mean to say that the sequence of coordinates > consisting of all zeros is arbitrary. The choice of the point *in the > real/hypothetical space* that is designated by the sequence of zero > coordinates is arbitrary. So what? All you are saying is that there is more than one coordinate system, and we can choose the one we like for any problem. Of course we can, and that's a good thing. >>> The significance of zero in real algebra is not that it is the origin >>> but rather that it is the additive and multiplicative zero: >>> >>> a + 0 = a for any real number a >>> a * 0 = 0 for any real number a >> >> I'm not sure what you mean by "additive and multiplicative zero", you >> appear to be conflating two different properties here. 0 is the >> additive *identity*, but 1 is the multiplicative identity: > > I mean that it has the properties that zero has when used in addition > and multiplication: > http://en.wikipedia.org/wiki/0_%28number%29#Elementary_algebra I see no reference to "additive and multiplicative zero" there. Did you make up that terminology? The *identity* element is a common mathematical term, but 1 is the multiplicative identity element. What you are describing is generally known as the "absorbing element" over multiplication: if X*a = X for any a, then X is an absorbing element under multiplication. http://en.wikipedia.org/wiki/Absorbing_element And by the way, the vector [0, 0] (generalised to however many dimensions you need) is not necessarily the only null (zero) vector. Some vector spaces have many null vectors with non-zero components. http://en.wikipedia.org/wiki/Zero_vector but I digress. The exact terminology doesn't really change anything, since everything you say about vector [0,0] applies equally to the point (0,0) in the Cartesian plane. [...] >>> There is however no meaningful sense in which points (as opposed to >>> vectors) can be added to each other or multiplied by anything, so >>> there is no zero point. >> >> I think that the great mathematician Carl Gauss would have something to >> say about that. > > Is the text below a quote? No. >> Points in the plane are equivalent to complex numbers, and you can >> certainly add and multiply complex numbers. Adding two points is >> equivalent to a translation; multiplication of a scalar with a point is >> equivalent to a scale transformation. Multiplying two points is >> equivalent to complex multiplication, which is a scale + a rotation. > > The last point is bizarre. Complex multiplication makes no sense when > you're trying to think about vectors. Draw a 2D plot and convince > yourself that the square of the point (0, 1) is (-1, 0). Um, yes? It's a rotation of the point (0, 1) by 90° counter-clockwise, with a scale factor of 1. Does that confuse you? It's a straight-forward geometric interpretation of multiplication in the complex plane. http://www.clarku.edu/~djoyce/complex/mult.html If you take the vector [0, 1] and rotate it by 90° counter-clockwise, you get the vector [-1, 0]. >> Oh look, that's exactly the same geometric interpretation as for >> vectors. Hardly surprising, since vectors are the magnitude and >> direction of a line from the origin to a point. > > Here it becomes clear that you have conflated "position vectors" with > vectors in general. Let me list some other examples of vectors that are > clearly not "from the origin to a point": > > velocity > acceleration > force > electric field > angular momentum > wave vector > > (I could go on) But they are, all of them, without exception. E.g. velocity is relative to some frame of reference, that is, which sets the "zero velocity" relative to which all other velocities are measured. Electric fields are relative to the vacuum far from any electric charges. And so on. I quote: "The angular momentum L of a particle about a given origin is defined as: L = r × p where r is the position vector of the particle relative to the origin, p is the linear momentum of the particle, and × denotes the cross product." http://en.wikipedia.org/wiki/Angular_momentum Is there some part of "about a given origin" which needs additional explanation? -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2012-11-12 01:10 +0000 |
| Message-ID | <mailman.3570.1352682390.27098.python-list@python.org> |
| In reply to | #33144 |
On 12/11/2012 00:31, Oscar Benjamin wrote: > > Plain wrong. Vectors are not defined *from any origin*. > So when the Captain says "full speed ahead, steer 245 degrees", you haven't the faintest idea where you're going, because you have no origin? -- Cheers. Mark Lawrence.
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2012-11-11 20:15 -0500 |
| Message-ID | <roy-052CF3.20151911112012@news.panix.com> |
| In reply to | #33158 |
In article <mailman.3570.1352682390.27098.python-list@python.org>,
Mark Lawrence <breamoreboy@yahoo.co.uk> wrote:
> On 12/11/2012 00:31, Oscar Benjamin wrote:
> >
> > Plain wrong. Vectors are not defined *from any origin*.
> >
>
> So when the Captain says "full speed ahead, steer 245 degrees", you
> haven't the faintest idea where you're going, because you have no origin?
Vectors have a length ("full speed ahead") and a direction ("245
degrees"). What they don't have is a fixed location in space. The
captain didn't say, "Full speed ahead, steer 245 degrees, from 45.0N,
20.0W".
In other words, you are correct. The order, "full speed ahead, steer
245 degrees", doesn't give you the faintest idea of where you're going.
If you were the helmsman, after you executed that order, without any
additional information (such as your current location), you would have
no idea what piece of land you will hit, or when you will hit it, if you
maintain your current course and speed.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.python
csiph-web