From: Andre W. <Andre.Wobst@Physik.Uni-Augsburg.DE> - 2002-02-24 22:35:10
|
Hi, jo...@us... wrote comments to design/arg.tex 1.5 checked in as version 1.6. In order to discuss them, I'll repost it here (a discussion within the LaTeX file seems quite hard to me). However, results coming out of this discussion should be merged to design/arg.tex. \item In my opinion, it is still not entirely clear, how we distinguish the use of \verb|arglist| and \verb|argdict| type parameters. Specifically, I think that a combination of both may in some cases be desirable. Consider for instance in the \verb|axis| example the case, where one wants to specify additionally the font size of the title. Would this not justify the use of an \verb|arglist| type argument? \item Probably the distinction is already clear, if one draws the line between graphical properties (color, line/text style/width, etc.) and other things. But where exactly then do fit in transformations, clipping, arrows, \dots? \item Maybe we should make \verb|arglist| type arguments the special case of \verb|argdict| arguments, namely \'a la \begin{verbatim} class main: def show(self, style=(), *args): for arg in args + tuple(style): print arg \end{verbatim} We could even think of something like the following: \begin{verbatim} class main: def show(self, style=(), trafo=(), *args): for arg in args + tuple(style) + tuple(trafo): print arg \end{verbatim} or maybe better \begin{verbatim} class main: def show(self, style=(), trafo=(), *args): for t in select_args(args, trafo, trafo.trafo): print t \end{verbatim} where \verb|select_arg(args, inst, _class)| is a helper routine, which selects all instances of the class \verb|_class| out of the lists \verb|args| and \verb|inst|, where in the latter one only instances of \verb|_class| are allowed. Maybe, we could also convert \verb|args| in advance to a list which can the modified in place by \verb|select_args|, and all found instances of \verb|_class| can be deleted. -- by _ _ _ Andre.Wobst@Physik.Uni-Augsburg.DE / \ \ / ) http://www.physik.uni-augsburg.de/~wobsta/ / _ \ \/\/ / watch a movie and learn about the mystery tippe top: (_/ \_)_/\_/ http://www.physik.uni-augsburg.de/~wobsta/tippetop/ |
From: Andre W. <Andre.Wobst@Physik.Uni-Augsburg.DE> - 2002-02-25 00:13:27
|
Hi, On 24.02.02, Andre Wobst posted a comment of Joerg Lehmann: > \item In my opinion, it is still not entirely clear, how we > distinguish the use of \verb|arglist| and \verb|argdict| type > parameters. Specifically, I think that a combination of both may in > some cases be desirable. Consider for instance in the \verb|axis| > example the case, where one wants to specify additionally the font > size of the title. Would this not justify the use of an > \verb|arglist| type argument? I claim we should try to not mix those parameter types. The major point is, that we will soon went into troubles, when we do so. Considering your case, what happens if you have not only one parameter being a text. My first idea about your example (which I already considered myself before) was just not to allow a change of the font size at that point -- or explicitly having a parameter for that. I do know that this is bad. It would lead to an inflating number of argdict-type arguments everywhere. So how about the following solution: import types class A: def __init__(self, color): self.color =3D color def __str__(self): return "<a color=3D\"%s\">" % self.color def show(text, *args): if type(text) =3D=3D types.TupleType: show(text[0], *(args + text[1:])) return for arg in args: print arg print text for arg in args: print "</>" def showtitle(text): show(text, A("red")) showtitle("text") showtitle(("text", A("blue"))) One has to make sure here, that the handling of multiple occurances of attributes like the class A in that example is ok. One shown possibility might be the correct order of applying the attributes, but that may vary by the subject of the routine. I thought about side effects of this solution, but it seems to be quite fine to me. If you like it too, I'll add it to arg.tex. > \item Probably the distinction is already clear, if one draws the line > between graphical properties (color, line/text style/width, etc.) > and other things. But where exactly then do fit in transformations, > clipping, arrows, \dots? You distinction is quite right, but I tried not to tighten it to that cases. However, it might be easier for the reader to get the point. But I'm not absolutely sure, if this technique is only appropriate to graphical properties. (It is not, I would say, but it's not clear to me if there are no such cases within PyX coming up.) Now about transformations, clipping ... those things we do think at the moment, that they are reserved specifically for canvas attributes. I claim, we do have both choises here. But I would prefere an arglist, because the attributes are already well organized in classes (we do have them anyway). Because of that, using argdict type arguments would lead to an unneeded clumsy notation. And shouldn't we include units to that stuff, too? Arrows are a different topic, I would guess. They do have something to do with paths. I'm not quite sure, if they are attributes of paths or what else we should do about it ... > \item Maybe we should make \verb|arglist| type arguments the special > case of \verb|argdict| arguments, namely \'a la > \begin{verbatim} > class main: > def show(self, style=3D(), *args): > for arg in args + tuple(style): > print arg >=20 > \end{verbatim} > We could even think of something like the following: > \begin{verbatim} > class main: > def show(self, style=3D(), trafo=3D(), *args): > for arg in args + tuple(style) + tuple(trafo): > print arg >=20 > \end{verbatim} > or maybe better > \begin{verbatim} > class main: > def show(self, style=3D(), trafo=3D(), *args): > for t in select_args(args, trafo, trafo.trafo): > print t >=20 > \end{verbatim} > where \verb|select_arg(args, inst, _class)| is a helper routine, which > selects all instances of the class \verb|_class| out of the lists > \verb|args| and \verb|inst|, where in the latter one only instances of > \verb|_class| are allowed. Maybe, we could also convert \verb|args| in > advance to a list which can the modified in place by > \verb|select_args|, and all found instances of \verb|_class| can be del= eted. Those selection things are already floating around in pyx/tex.py. I do need them there because I exactly do have to sort out the different attributes by hand (for (La)TeX). We should consider throwing that part out of pyx/tex.py and putting it into something like listattr.py, where we define also a father of all arglist-type attributes. And, back to the point. If we use arglists at all those cases (like the canvas constructor), we should still not doing it at the case of an axis when putting a partitioning system into it. Why? Well, I'll show you: 1. Consider something like axis(min =3D None). For sure we wont have to write a class for min. So we use an argdict. 2. Lets assume we do have a partitioning system class genpart. And lets assume we're able to put it into a list at the end of the axis constructor. So we have axis(min =3D None, genpart(opt =3D 10)) 3. Lets now assume, we derive an axis to titleaxis adding a title. As I have already shown, we do have to add an argdict for handling arguments which have to be handed over to the base class. Additionally, we do have an arglist. So we write: __init__(self, title =3D "", *list, **dict). 4. Now, explain the order of the arguments of titleaxis ... even if it would work. But it doesn't at all. It would look like: class genpart: def __init__(self, opt =3D 5): self.opt =3D opt class axis: def __init__(self, min =3D None, max =3D None, *list): self.min =3D min self.max =3D max self.others =3D list # may e.g. hold a genpart class titleaxis(axis): def __init__(self, title =3D "", *list, **dict): axis.__init__(self, *list, **dict) self.title =3D title titleaxis(genpart(opt =3D 10), title =3D "", min =3D 1) # doesn't work ... titleaxis(title =3D "", genpart(opt =3D 10), min =3D 1) # doesn't work ..= . either It does "compile", but it doesn't run -- Python just doesn't allow for those constructions. Or am I wrong? Is there really a way to do that? If there is, I would like to see it. I may even reconsider my point of view ... but I don't expect that. Andr=E9 --=20 by _ _ _ Andre.Wobst@Physik.Uni-Augsburg.DE / \ \ / ) http://www.physik.uni-augsburg.de/~wobsta/ / _ \ \/\/ / watch a movie and learn about the mystery tippe top: (_/ \_)_/\_/ http://www.physik.uni-augsburg.de/~wobsta/tippetop/ |
From: Joerg L. <Joe...@ph...> - 2002-02-25 10:24:32
|
Hi, On 25.02.02, Andre Wobst wrote: > Hi, >=20 > On 24.02.02, Andre Wobst posted a comment of Joerg Lehmann: > > \item In my opinion, it is still not entirely clear, how we > > distinguish the use of \verb|arglist| and \verb|argdict| type > > parameters. Specifically, I think that a combination of both may in > > some cases be desirable. Consider for instance in the \verb|axis| > > example the case, where one wants to specify additionally the font > > size of the title. Would this not justify the use of an > > \verb|arglist| type argument? >=20 > I claim we should try to not mix those parameter types. The major > point is, that we will soon went into troubles, when we do so. > Considering your case, what happens if you have not only one parameter > being a text. My first idea about your example (which I already > considered myself before) was just not to allow a change of the font > size at that point -- or explicitly having a parameter for that. I do > know that this is bad. It would lead to an inflating number of > argdict-type arguments everywhere. So how about the following > solution: >=20 > import types >=20 > class A: > def __init__(self, color): > self.color =3D color > def __str__(self): > return "<a color=3D\"%s\">" % self.color >=20 > def show(text, *args): > if type(text) =3D=3D types.TupleType: > show(text[0], *(args + text[1:])) > return > for arg in args: > print arg > print text > for arg in args: > print "</>" >=20 > def showtitle(text): > show(text, A("red")) >=20 > showtitle("text") > showtitle(("text", A("blue"))) >=20 > One has to make sure here, that the handling of multiple occurances of > attributes like the class A in that example is ok. One shown > possibility might be the correct order of applying the attributes, but > that may vary by the subject of the routine. Ordering is certainly a problem, not only for the routine, but also=20 for the user. There has to be some inherent logic behind that, which the user can easily remember. But this only as a sidenote... > I thought about side effects of this solution, but it seems to be > quite fine to me. If you like it too, I'll add it to arg.tex. I'm not quite sure about the solution. Actually, I don't like it very much, it seems not very natural to me. Besides, I think, that it just moves the mixture of arglist and argdict like arguments on another level. So why don't we do it rightaway. If it is clearly understandable by the user, wheter an argument is argdict or arglist, the why don't use both together. And again, if arglist is a special case of argdict, even better (see e.g. the style=3D case below). >=20 > > \item Probably the distinction is already clear, if one draws the lin= e > > between graphical properties (color, line/text style/width, etc.) > > and other things. But where exactly then do fit in transformations, > > clipping, arrows, \dots? >=20 > You distinction is quite right, but I tried not to tighten it to that > cases. However, it might be easier for the reader to get the point. > But I'm not absolutely sure, if this technique is only appropriate to > graphical properties. (It is not, I would say, but it's not clear to > me if there are no such cases within PyX coming up.) >=20 > Now about transformations, clipping ... those things we do think at > the moment, that they are reserved specifically for canvas attributes. > I claim, we do have both choises here. But I would prefere an arglist, > because the attributes are already well organized in classes (we do > have them anyway). Because of that, using argdict type arguments would > lead to an unneeded clumsy notation. And shouldn't we include units to > that stuff, too? I repeat, maybe we should leave this to the user, i.e. we should allow for a mixture of both. Otherwise, I agree, that the momentary treatment of units as a special case should be changed. > Arrows are a different topic, I would guess. They do have something to > do with paths. I'm not quite sure, if they are attributes of paths or > what else we should do about it ... I thought a little about that, but now it seems clear to me, that arrows are attributes of paths _during_ the drawing on the canvas. For instance, we need to know something about the current linewidth in order to be able to draw reasonable arrows. > > \item Maybe we should make \verb|arglist| type arguments the special > > case of \verb|argdict| arguments, namely \'a la > > \begin{verbatim} > > class main: > > def show(self, style=3D(), *args): > > for arg in args + tuple(style): > > print arg > >=20 > > \end{verbatim} > > We could even think of something like the following: > > \begin{verbatim} > > class main: > > def show(self, style=3D(), trafo=3D(), *args): > > for arg in args + tuple(style) + tuple(trafo): > > print arg > >=20 > > \end{verbatim} > > or maybe better > > \begin{verbatim} > > class main: > > def show(self, style=3D(), trafo=3D(), *args): > > for t in select_args(args, trafo, trafo.trafo): > > print t > >=20 > > \end{verbatim} > > where \verb|select_arg(args, inst, _class)| is a helper routine, whic= h > > selects all instances of the class \verb|_class| out of the lists > > \verb|args| and \verb|inst|, where in the latter one only instances o= f > > \verb|_class| are allowed. Maybe, we could also convert \verb|args| i= n > > advance to a list which can the modified in place by > > \verb|select_args|, and all found instances of \verb|_class| can be d= eleted. >=20 > Those selection things are already floating around in pyx/tex.py. I do > need them there because I exactly do have to sort out the different > attributes by hand (for (La)TeX). We should consider throwing that > part out of pyx/tex.py and putting it into something like listattr.py, > where we define also a father of all arglist-type attributes. Indeed. We should pull this out of tex.py. And in my opinion, we should extend this routine to a point, where things like canvas(unit.unit()) and canvas(unit=3Dunit.unit()) are equivalent.=20 =20 > And, back to the point. If we use arglists at all those cases (like > the canvas constructor), we should still not doing it at the case of > an axis when putting a partitioning system into it. Why? Well, I'll > show you: >=20 > 1. Consider something like axis(min =3D None). For sure we wont have to > write a class for min. So we use an argdict. >=20 > 2. Lets assume we do have a partitioning system class genpart. And > lets assume we're able to put it into a list at the end of the axis > constructor. So we have axis(min =3D None, genpart(opt =3D 10)) >=20 > 3. Lets now assume, we derive an axis to titleaxis adding a title. As > I have already shown, we do have to add an argdict for handling > arguments which have to be handed over to the base class. > Additionally, we do have an arglist. So we write: > __init__(self, title =3D "", *list, **dict). >=20 > 4. Now, explain the order of the arguments of titleaxis ... even if it > would work. But it doesn't at all. >=20 > It would look like: >=20 > class genpart: > def __init__(self, opt =3D 5): > self.opt =3D opt >=20 > class axis: > def __init__(self, min =3D None, max =3D None, *list): > self.min =3D min > self.max =3D max > self.others =3D list # may e.g. hold a genpart >=20 > class titleaxis(axis): > def __init__(self, title =3D "", *list, **dict): > axis.__init__(self, *list, **dict) > self.title =3D title >=20 > titleaxis(genpart(opt =3D 10), title =3D "", min =3D 1) # doesn't work = ... > titleaxis(title =3D "", genpart(opt =3D 10), min =3D 1) # doesn't work = ... either >=20 > It does "compile", but it doesn't run -- Python just doesn't allow for > those constructions. Or am I wrong? Is there really a way to do that? > If there is, I would like to see it. I may even reconsider my point of > view ... but I don't expect that. Why don't we just use self.title =3D dict.get("title", "") and don't ever specify the parameters explicitly in the function definition. J=F6rg =20 |
From: Andre W. <Andre.Wobst@Physik.Uni-Augsburg.DE> - 2002-02-25 14:29:59
|
Hi, On 25.02.02, Joerg Lehmann wrote: > > On 24.02.02, Andre Wobst posted a comment of Joerg Lehmann: > > import types > >=20 > > class A: > > def __init__(self, color): > > self.color =3D color > > def __str__(self): > > return "<a color=3D\"%s\">" % self.color > >=20 > > def show(text, *args): > > if type(text) =3D=3D types.TupleType: > > show(text[0], *(args + text[1:])) ^---- ordering > > return > > for arg in args: > > print arg > > print text > > for arg in args: > > print "</>" > >=20 > > def showtitle(text): > > show(text, A("red")) > >=20 > > showtitle("text") > > showtitle(("text", A("blue"))) > >=20 > > One has to make sure here, that the handling of multiple occurances o= f > > attributes like the class A in that example is ok. One shown > > possibility might be the correct order of applying the attributes, bu= t > > that may vary by the subject of the routine. >=20 > Ordering is certainly a problem, not only for the routine, but also=20 > for the user. There has to be some inherent logic behind that, which > the user can easily remember. But this only as a sidenote... I think, the ordering is quite natural --- not a problem at all. In the case (as above) where the parameters do fullfill a stack like behavior, you just have to apply the most inside arguments last (closest to text in the example above). They are somehow strongest bound to the text. So there is some very intrinsic logic behind it. > > I thought about side effects of this solution, but it seems to be > > quite fine to me. If you like it too, I'll add it to arg.tex. >=20 > I'm not quite sure about the solution. Actually, I don't like it very > much, it seems not very natural to me. Besides, I think, that it just > moves the mixture of arglist and argdict like arguments on another > level. So why don't we do it rightaway. If it is clearly > understandable by the user, wheter an argument is argdict or arglist, > the why don't use both together. And again, if arglist is a special > case of argdict, even better (see e.g. the style=3D case below). I think, we do *not* mix arglist and argdicts here. And I'll add another example in order to clearify my problems (show may be defined as above): def showtitle(title =3D "some default", subtitle =3D "some default"): show(title, A("red")) show(subtitle) We can do now: showtitle("text") showtitle(title =3D "text") showtitle(title =3D "text1", subtitle =3D "text2") showtitle(title =3D ("text1", A("blue")), subtitle =3D "text2") showtitle(title =3D "text1", subtitle =3D ("text2", A("green"))) Both, title and subtitle could have some attribute of class A. You can't distinguish it without tighten this attribute to title itself. (Please don't come up with some way getting this out of the ordering of the arguments.) So title and subtitle themself are just argdict arguments, but they *themself* are arglists. They can get parameters exactly like the show routine itself. At the same time, showtitle can easily provide default attributes to a title (like the color red in the examle). To my eyes, this technique is very transparent for both developers and users. > > Arrows are a different topic, I would guess. They do have something t= o > > do with paths. I'm not quite sure, if they are attributes of paths or > > what else we should do about it ... >=20 > I thought a little about that, but now it seems clear to me, that > arrows are attributes of paths _during_ the drawing on the canvas. > For instance, we need to know something about the current linewidth in > order to be able to draw reasonable arrows. That sounds good. This would mean, a draw attribute can actually do more than just add some postscript in front the draw. We should get some technique into the draw routine, which allows for that (e.g. the arrow attribute has to get the path to be drawn somehow). I think, we can do that somehow. But this will need some thoughts ... > Indeed. We should pull this out of tex.py. And in my opinion, we > should extend this routine to a point, where things like >=20 > canvas(unit.unit()) > and > canvas(unit=3Dunit.unit()) > are equivalent.=20 Let's first (at least try to) clean up our minds about that mixturing. > > ... > > titleaxis(genpart(opt =3D 10), title =3D "", min =3D 1) # doesn't wor= k ... > > titleaxis(title =3D "", genpart(opt =3D 10), min =3D 1) # doesn't wor= k ... either > > ... >=20 > Why don't we just use >=20 > self.title =3D dict.get("title", "") >=20 > and don't ever specify the parameters explicitly in the function > definition. You're right that this would be a solution. But do we really want to give up the standard way of having default arguments? We could never write define axis.__init__(self, min =3D None, max =3D None) anymore. Instead, we would get a much less convenient way of writing parameters. And another crutial thing. What happens if somebody misspells title in his parameter list ... he would never get any warning about writing tilte ... the value of the parameter would just be ignored. I do claim, that we should not rewrite the hole argument handling by ourselfs. The solution you suggest does that. Andr=E9 --=20 by _ _ _ Andre.Wobst@Physik.Uni-Augsburg.DE / \ \ / ) http://www.physik.uni-augsburg.de/~wobsta/ / _ \ \/\/ / watch a movie and learn about the mystery tippe top: (_/ \_)_/\_/ http://www.physik.uni-augsburg.de/~wobsta/tippetop/ |
From: Joerg L. <jo...@us...> - 2002-02-25 15:57:05
|
On 25.02.02, Andre Wobst wrote: > Hi, >=20 > On 25.02.02, Joerg Lehmann wrote: > > > On 24.02.02, Andre Wobst posted a comment of Joerg Lehmann: > > > import types > > >=20 > > > def show(text, *args): > > > if type(text) =3D=3D types.TupleType: > > > show(text[0], *(args + text[1:])) > ^---- ordering > > > return > > > for arg in args: > > > print arg > > > print text > > > for arg in args: > > > print "</>" > > >=20 >=20 > I think, the ordering is quite natural --- not a problem at all. In > the case (as above) where the parameters do fullfill a stack like > behavior, you just have to apply the most inside arguments last > (closest to text in the example above). They are somehow strongest > bound to the text. So there is some very intrinsic logic behind it. Fair enough. > I think, we do *not* mix arglist and argdicts here. And I'll add > another example in order to clearify my problems (show may be defined > as above): >=20 > def showtitle(title =3D "some default", subtitle =3D "some default"): > show(title, A("red")) > show(subtitle) >=20 > We can do now: >=20 > showtitle("text") > showtitle(title =3D "text") > showtitle(title =3D "text1", subtitle =3D "text2") > showtitle(title =3D ("text1", A("blue")), subtitle =3D "text2") So you have to A("Blue") and A("red") for title, where the second one overrides the first one, which should presumably be the default? But the output corresponding to such a solution wouldn't be very nice, would it? > showtitle(title =3D "text1", subtitle =3D ("text2", A("green"))) > Both, title and subtitle could have some attribute of class A. You > can't distinguish it without tighten this attribute to title itself. > (Please don't come up with some way getting this out of the ordering > of the arguments.) So title and subtitle themself are just argdict > arguments, but they *themself* are arglists. They can get parameters > exactly like the show routine itself. At the same time, showtitle can > easily provide default attributes to a title (like the color red in > the examle). To my eyes, this technique is very transparent for both > developers and users. Ok, this is certainly an advantage of such an approach (but see my comment above), though it is not perfectly object oriented. Maybe, we nee= d=20 compound objects, which glue together some text or path with style proper= ties.=20 I already though about something like this for paths. But this is just an= idea. > > > Arrows are a different topic, I would guess. They do have something= to > > > do with paths. I'm not quite sure, if they are attributes of paths = or > > > what else we should do about it ... > >=20 > > I thought a little about that, but now it seems clear to me, that > > arrows are attributes of paths _during_ the drawing on the canvas. > > For instance, we need to know something about the current linewidth i= n > > order to be able to draw reasonable arrows. >=20 > That sounds good. This would mean, a draw attribute can actually do > more than just add some postscript in front the draw. We should get > some technique into the draw routine, which allows for that (e.g. > the arrow attribute has to get the path to be drawn somehow). I think, > we can do that somehow. But this will need some thoughts ... Yes, but we need something like that. >=20 > > Indeed. We should pull this out of tex.py. And in my opinion, we > > should extend this routine to a point, where things like > >=20 > > canvas(unit.unit()) > > and > > canvas(unit=3Dunit.unit()) > > are equivalent.=20 >=20 > Let's first (at least try to) clean up our minds about that mixturing. >=20 > > > ... > > > titleaxis(genpart(opt =3D 10), title =3D "", min =3D 1) # doesn't w= ork ... > > > titleaxis(title =3D "", genpart(opt =3D 10), min =3D 1) # doesn't w= ork ... either > > > ... > >=20 > > Why don't we just use > >=20 > > self.title =3D dict.get("title", "") > >=20 > > and don't ever specify the parameters explicitly in the function > > definition. >=20 > You're right that this would be a solution. But do we really want to > give up the standard way of having default arguments? We could never Isn't this a standard way? I saw it many time before. > write define axis.__init__(self, min =3D None, max =3D None) anymore. > Instead, we would get a much less convenient way of writing > parameters. And another crutial thing. What happens if somebody > misspells title in his parameter list ... he would never get any > warning about writing tilte ... the value of the parameter would just > be ignored. Concerning your last point: this could be avoided if we track the use=20 of all parameter names. If there is eventually some parameter left, we could throw an exception... But I still think, that such a solution could be automated very well, and therefore it would be possible. > I do claim, that we should not rewrite the hole argument handling by > ourselfs. The solution you suggest does that. Right, but see previous sentence. J=F6rg |
From: Andre W. <Andre.Wobst@Physik.Uni-Augsburg.DE> - 2002-02-25 17:35:09
|
Hi, On 25.02.02, Joerg Lehmann wrote: > > I think, we do *not* mix arglist and argdicts here. And I'll add > > another example in order to clearify my problems (show may be defined > > as above): > >=20 > > def showtitle(title =3D "some default", subtitle =3D "some default"): > > show(title, A("red")) > > show(subtitle) > >=20 > > We can do now: > >=20 > > showtitle("text") > > showtitle(title =3D "text") > > showtitle(title =3D "text1", subtitle =3D "text2") > > showtitle(title =3D ("text1", A("blue")), subtitle =3D "text2") >=20 > So you have to A("Blue") and A("red") for title, where the second one > overrides the first one, which should presumably be the default? Indeed. > But the output corresponding to such a solution wouldn't be very > nice, would it? Yes, for that case it is bad. But the behavior is quite right, I suppose. It is just a feature of that color change, that it destroys everything about the previous color change, so that it doesn't make sense to apply it twice. We should therefore just remove the color change that wouldn't take effect because it is overwritten. This task should be fullfilled by the show/draw (whatever) routine. In order to be able to do this, it might use some information given within the attributes, or ask the attributes themselfes and additional we can make use of the class tree for doing so. However, I would suggest not to implement that at the moment, because it is not crucial at all. We should be sure, that it can be done and that's it for the moment. Of course, you're welcome to already implement this, but I think, it is not crucial in order to prepare version 0.1.0. BTW, there are cases, where it is usefull to apply the change twice, although it is the same attribute. Immediately transformations come into my mind. We discussed, that we should reserve that for an subcanvas (which I still think is a good idea). But nevertheless, because we're suppose to use an arglist there too, at that point we must not throw away any transformation ... > > Both, title and subtitle could have some attribute of class A. You > > can't distinguish it without tighten this attribute to title itself. > > (Please don't come up with some way getting this out of the ordering > > of the arguments.) So title and subtitle themself are just argdict > > arguments, but they *themself* are arglists. They can get parameters > > exactly like the show routine itself. At the same time, showtitle can > > easily provide default attributes to a title (like the color red in > > the examle). To my eyes, this technique is very transparent for both > > developers and users. >=20 > Ok, this is certainly an advantage of such an approach (but see my > comment above), though it is not perfectly object oriented. Maybe, > we need compound objects, which glue together some text or path with > style properties. I already though about something like this for > paths. But this is just an idea. You're right, that that solution is not perfectly object oriented. The main advantage of not having objects there is the easy way of writing it. And --- in that sense --- the tuple lists are just the glue. And I do have another strong argument (I think). Think about a string having some substitution parameters (%), followed by a % and then a tuple. It is exaclty the same construction, isn't it? > > > Why don't we just use > > >=20 > > > self.title =3D dict.get("title", "") > > >=20 > > > and don't ever specify the parameters explicitly in the function > > > definition. > >=20 > > You're right that this would be a solution. But do we really want to > > give up the standard way of having default arguments? We could never >=20 > Isn't this a standard way? I saw it many time before. I've also seen that before. But I think it's a bad solution. > > write define axis.__init__(self, min =3D None, max =3D None) anymore. > > Instead, we would get a much less convenient way of writing > > parameters. And another crutial thing. What happens if somebody > > misspells title in his parameter list ... he would never get any > > warning about writing tilte ... the value of the parameter would just > > be ignored. >=20 > Concerning your last point: this could be avoided if we track the use=20 > of all parameter names. If there is eventually some parameter left, we > could throw an exception... > But I still think, that such a solution could be automated very well, > and therefore it would be possible. Do you mean to create a kind of meta-class providing this. Or would you suggest to always have to call that kind of methods. I encourage your idea. It would also help out of the multiple inheritance problem (which is indeed a huge disadvantage from a design point of view). But I was trying to make the point, that we could try not to go along that line. Andr=E9 --=20 by _ _ _ Andre.Wobst@Physik.Uni-Augsburg.DE / \ \ / ) http://www.physik.uni-augsburg.de/~wobsta/ / _ \ \/\/ / watch a movie and learn about the mystery tippe top: (_/ \_)_/\_/ http://www.physik.uni-augsburg.de/~wobsta/tippetop/ |
From: Andre W. <Andre.Wobst@Physik.Uni-Augsburg.DE> - 2002-02-26 12:15:17
|
Hi, On 25.02.02, Andre Wobst wrote: > > Ok, this is certainly an advantage of such an approach (but see my > > comment above), though it is not perfectly object oriented. Maybe, > > we need compound objects, which glue together some text or path with > > style properties. I already though about something like this for > > paths. But this is just an idea. >=20 > You're right, that that solution is not perfectly object oriented. The > main advantage of not having objects there is the easy way of writing > it. And --- in that sense --- the tuple lists are just the glue. And I > do have another strong argument (I think). Think about a string having > some substitution parameters (%), followed by a % and then a tuple. It > is exaclty the same construction, isn't it? I do have some additional comments about that. They show, that it is not that easy with that case of a routine taking a string together with properties of that very string. First of all, I was thinking along the line of ``%'' and came up with just an idea, how a nice design would be (although it would lead to a "new language", which is not a possible solution ... I do remember very well, that we once tried to make PyX look more like gle, but fortunately we gave up). But still, consider to write "the glue" (combining "text" and it's attributes) like a string with substitutions using an alleged ``@'' operator. We could write: "text" "text" @ fontsize.small "text" @ (fontsize.small, halign.center, ) ... and so on. I'm quite puzzled about that. (BTW: We would need something like ``\makeatoperator'' ... but while in TeX you make that change global, you would need ``\WithinExpression{\makeatoperator}''. Anyway, it is funny that you can switch the type class of your characters in TeX.) Ok, now I do come to a real problem we do have to consider anyway. Suppose you do have some kind of forming a text-with-attribute. What about a routine reply(), which wants to add a "Re: " in front of a subject? Consider, that the subject already have a attribute supplied by the user (like a("red")), but this subject subroutine add's first some other text (the "Re: ") and than another attribute (like a color blue). Ok, the result would/should look like <a color=3D"blue">Re: <a color=3D"red">spam</a></a>. What the main point here is, that this text-with-attribute has to behave like a text itself in order to get the add working without considering, that we do not have a text, but a text-with-attribute. Finally (for the moment), I would suggest to think about a class combine. I do not know, if this can be done without side effects. But it should work the following way: -- combine("spam", a("red")) out of that we need to be able to create the correct output (e.g. performing the attribute change a("red") to "spam" (whatever that attribute change has to be worked out in the end) -- combine(type/class - instance) should be allowed for any argument -- combine(type/class, a("red"), a("blue")) should just be able -- combine(type/class - instance, <something>) should behave like the type/class - instance itself. This would mean, the attributes are just attributes (they do not modify the behavior of the type/class - instance against operators). -- combine("spam", a("red")) + "eggs" (and other those constructions) should just work like expected. I do think, this case needs to be subject of detailed discussion, how it should work. I do not yet know, what type of object that thing is. For the moment I guess we would need a encapsulation class for that: combineop(op_add, combine("spam", a("red")), "eggs") -- combineop(<op>, type/class - instance, type/class - instance)) should behave like using the appropriate operator for the two classes supplied. <op> may not be any allowed for all operators for the moment. As long as we have only strings and lists (paths?) as type/class - instances, we do not need a multiply operator (just as an example). -- combine("spam") < combine("eggs") (and other those constructions) should just call the appropriate operator for "spam" < "eggs" By having that, we could throw away arglists as a matter of principle. While I would suggest to still accept canvas.draw(path(...), linewidth(...)) It should automatically behave like canvas.draw(combine(path(...), linewidth(...)) That's it for the moment. I would feel very comfortable having a combine like described above. The idea with the ``@'' is just nice, but combine is quite nice too and does not leave the python language. Any comments are appreciated. Andr=E9 --=20 by _ _ _ Andre.Wobst@Physik.Uni-Augsburg.DE / \ \ / ) http://www.physik.uni-augsburg.de/~wobsta/ / _ \ \/\/ / watch a movie and learn about the mystery tippe top: (_/ \_)_/\_/ http://www.physik.uni-augsburg.de/~wobsta/tippetop/ |
From: Joerg L. <jo...@us...> - 2002-02-26 14:14:25
|
On 26.02.02, Andre Wobst wrote: > I do have some additional comments about that. They show, that it is > not that easy with that case of a routine taking a string together > with properties of that very string. >=20 > First of all, I was thinking along the line of ``%'' and came up with > just an idea, how a nice design would be (although it would lead to a > "new language", which is not a possible solution ... I do remember > very well, that we once tried to make PyX look more like gle, but > fortunately we gave up). >=20 > But still, consider to write "the glue" (combining "text" and it's > attributes) like a string with substitutions using an alleged ``@'' > operator. We could write: > "text" > "text" @ fontsize.small > "text" @ (fontsize.small, halign.center, ) > ... and so on. I'm quite puzzled about that. (BTW: We would need > something like ``\makeatoperator'' ... but while in TeX you make that > change global, you would need ``\WithinExpression{\makeatoperator}''. > Anyway, it is funny that you can switch the type class of your > characters in TeX.) True, very flexible and thus also somehow ugly... > Ok, now I do come to a real problem we do have to consider anyway. > Suppose you do have some kind of forming a text-with-attribute. What > about a routine reply(), which wants to add a "Re: " in front of a > subject? Consider, that the subject already have a attribute supplied > by the user (like a("red")), but this subject subroutine add's first > some other text (the "Re: ") and than another attribute (like a color > blue). Ok, the result would/should look like > <a color=3D"blue">Re: <a color=3D"red">spam</a></a>. > What the main point here is, that this text-with-attribute has to > behave like a text itself in order to get the add working without > considering, that we do not have a text, but a text-with-attribute. So the simple solution won't work here... > Finally (for the moment), I would suggest to think about a class > combine. I do not know, if this can be done without side effects. But > it should work the following way: This is exactly, what I meant with object oriented, i.e. a glue class. > -- combine("spam", a("red")) + "eggs" > (and other those constructions) should just work like expected. > I do think, this case needs to be subject of detailed discussion, > how it should work. I do not yet know, what type of object that > thing is. For the moment I guess we would need a encapsulation > class for that: > combineop(op_add, combine("spam", a("red")), "eggs") >=20 > -- combineop(<op>, type/class - instance, type/class - instance)) > should behave like using the appropriate operator for the two > classes supplied. > <op> may not be any allowed for all operators for the moment. > As long as we have only strings and lists (paths?) as > type/class - instances, we do not need a multiply operator > (just as an example). Ok, it starts to become complicated, maybe combineop can just be a special case of combine. But I think, such things need a little more considering.=20 > -- combine("spam") < combine("eggs") > (and other those constructions) should just call the appropriate > operator for "spam" < "eggs" Hmm, not absolutely necessary, if not in general ill defined... > By having that, we could throw away arglists as a matter of principle. > While I would suggest to still accept > canvas.draw(path(...), linewidth(...)) > It should automatically behave like > canvas.draw(combine(path(...), linewidth(...)) Maybe. >=20 > That's it for the moment. I would feel very comfortable having a > combine like described above. The idea with the ``@'' is just nice, > but combine is quite nice too and does not leave the python language. True. But in my opinion the details of something like combine still have to be worked out. We should not do things in a too complicated way!=20 Hey, just to go over to something completely different. How about dropping the unit in canvas, i.e. the late evaluation of units? I'm becoming more and more in favour of it, since I don't like: - passing a canvas for the intersection of bezier curves - passing a canvas for tranforming a arct into a bezier curves Both times, the canvas is absolutely necessary, so we are doing something wrong. At the moment I'm thinking of a solution, where you can only use uvw via a instance u("1 u mm"), which is the=20 instance of a class generated by a metaclass unit: u=3Dunit.unit(scale=3D{'u':1.5,...}) Ok, metaclasses, but it would be a perfect fit ;)) J=F6rg |
From: Andre W. <Andre.Wobst@Physik.Uni-Augsburg.DE> - 2002-02-26 15:12:32
|
Hi, On 26.02.02, Joerg Lehmann wrote: > Hey, just to go over to something completely different. (Next time it would be better to start a new thread for those things. Otherwise we'll end up in just one subject line with 100 postings ...) > How about > dropping the unit in canvas, i.e. the late evaluation of units? > I'm becoming more and more in favour of it, since I don't like: >=20 > - passing a canvas for the intersection of bezier curves > - passing a canvas for tranforming a arct into a bezier curves The same for the h-size problem in tex.py. > Both times, the canvas is absolutely necessary, so we are doing > something wrong. At the moment I'm thinking of a solution, where > you can only use uvw via a instance u("1 u mm"), which is the=20 > instance of a class generated by a metaclass unit: >=20 > u=3Dunit.unit(scale=3D{'u':1.5,...}) >=20 > Ok, metaclasses, but it would be a perfect fit ;)) One problem on dropping that out of the canvas is, that we then do not know anymore how to change the unit, which we use, if we just write plain numbers. If I see through it correctly, that was the reason for the marriage of the canvas and the units and therefore for the late evaluation. What about just saying t.text(1,2,"bla"). In what units are these 1 and 2 are measured? (Same for paths, like lineto and thatever else ...) Andr=E9 --=20 by _ _ _ Andre.Wobst@Physik.Uni-Augsburg.DE / \ \ / ) http://www.physik.uni-augsburg.de/~wobsta/ / _ \ \/\/ / watch a movie and learn about the mystery tippe top: (_/ \_)_/\_/ http://www.physik.uni-augsburg.de/~wobsta/tippetop/ |
From: Joerg L. <jo...@us...> - 2002-02-26 15:30:04
|
On 26.02.02, Andre Wobst wrote: > (Next time it would be better to start a new thread for those things. > Otherwise we'll end up in just one subject line with 100 postings ...) I like long threads, which become more and more offtopic :)) > > How about > > dropping the unit in canvas, i.e. the late evaluation of units? > > I'm becoming more and more in favour of it, since I don't like: > > > > - passing a canvas for the intersection of bezier curves > > - passing a canvas for tranforming a arct into a bezier curves > > The same for the h-size problem in tex.py. I know. So we have three, and maybe even more in the future... > One problem on dropping that out of the canvas is, that we then do not > know anymore how to change the unit, which we use, if we just write > plain numbers. If I see through it correctly, that was the reason for > the marriage of the canvas and the units and therefore for the late > evaluation. What about just saying t.text(1,2,"bla"). In what units > are these 1 and 2 are measured? (Same for paths, like lineto and > thatever else ...) Yes, that's true. But maybe we can use a hack, which stores the base unit globally (as a static property of the unit class). Isn't something like that possible in Python 2.2? All the routines would then do something like class moveto(pathel): def __init__(self, x, y): self.x = unit.unit.pt(x) self.y = unit.unit.pt(y) unit.unit.pt would then be a class method (I don't remember the correct name), which knows the default unit. With such a solution we could also retain the present semantics, for instance: moveto("0.5 v mm", 3) I haven't tried it yet, but probably it works. Joerg |
From: Andre W. <Andre.Wobst@Physik.Uni-Augsburg.DE> - 2002-02-26 16:31:28
|
Hi, On 26.02.02, Joerg Lehmann wrote: > > (Next time it would be better to start a new thread for those things. > > Otherwise we'll end up in just one subject line with 100 postings ...= ) >=20 > I like long threads, which become more and more offtopic :)) At least, I do have changed the subject line and discuss only that part for the moment ... > > > How about > > > dropping the unit in canvas, i.e. the late evaluation of units? > > > I'm becoming more and more in favour of it, since I don't like: > > >=20 > > > - passing a canvas for the intersection of bezier curves > > > - passing a canvas for tranforming a arct into a bezier curves > >=20 > > The same for the h-size problem in tex.py. >=20 > I know. So we have three, and maybe even more in the future... For sure. > > One problem on dropping that out of the canvas is, that we then do no= t > > know anymore how to change the unit, which we use, if we just write > > plain numbers. If I see through it correctly, that was the reason for > > the marriage of the canvas and the units and therefore for the late > > evaluation. What about just saying t.text(1,2,"bla"). In what units > > are these 1 and 2 are measured? (Same for paths, like lineto and > > thatever else ...) >=20 > Yes, that's true. But maybe we can use a hack, which stores the base=20 > unit globally (as a static property of the unit class). Isn't > something like that possible in Python 2.2? I don't think its related to Python 2.2. Such a construction is available all the time --- or maybe I have misunderstood you. Do you mean something like this: class unit: defaultunit =3D "1 u cm" ... You should be able to access that all the time and this value is global (I might be wrong here but I do remember something like this). However, if we do such a construction, we could also put that defaultunit outside of the unit class. It is global for the unit module (and in die end global for pyx). It might be natural (I feel quite sure), that we then do have a global unit variable. For the moment, we don't have it and therefore run into the troubles you talked about. We may know just decide, what to do. I would say, that it is ok. Even so, there is a way out by doing: import pyx as pyx1 import pyx as pyx2 Whenever you use now pyx1, you should be able to access the pyx1 global defaultunit, whereas you do the same within pyx2. I haven't tried it (have never done something like that), but hopefully this is possible. The key for doing so, is that the lineto for example doesn't just look for pyx.unit.defaultunit, but for self.???.unit.defaultunit. The question is, if all that is available in the modules namespace somehow. But I guess so. We should try it. It would be a nice starting point for writing a arg.tex like proposal on units ... Andr=E9 --=20 by _ _ _ Andre.Wobst@Physik.Uni-Augsburg.DE / \ \ / ) http://www.physik.uni-augsburg.de/~wobsta/ / _ \ \/\/ / watch a movie and learn about the mystery tippe top: (_/ \_)_/\_/ http://www.physik.uni-augsburg.de/~wobsta/tippetop/ |
From: Joerg L. <jo...@us...> - 2002-02-26 16:49:55
|
On 26.02.02, Andre Wobst wrote: > > Yes, that's true. But maybe we can use a hack, which stores the base=20 > > unit globally (as a static property of the unit class). Isn't > > something like that possible in Python 2.2? >=20 > I don't think its related to Python 2.2. Such a construction is > available all the time --- or maybe I have misunderstood you. Do you > mean something like this: You're right , that' of course already possible. New in Python 2.2 are so called static methods. And of course metaclasses, but probably we don't need them. They would at least allow something like u1=3Dunit.unit(scale=3D...) u2=3Dunit.unit(scale=3D...) moveto(u1("..."), u2("...")) but still the default unit would be the same. So this is probably not a good idea. > It might be natural (I feel quite sure), that we then do have a global > unit variable. For the moment, we don't have it and therefore run into > the troubles you talked about. We may know just decide, what to do. I > would say, that it is ok. Even so, there is a way out by doing: I also think, that we should do it like that and drop our present scheme. It's really too complicated and the user gains not very much from it. >=20 > import pyx as pyx1 > import pyx as pyx2 >=20 > Whenever you use now pyx1, you should be able to access the pyx1 > global defaultunit, whereas you do the same within pyx2. I haven't > tried it (have never done something like that), but hopefully this is > possible. The key for doing so, is that the lineto for example doesn't > just look for pyx.unit.defaultunit, but for self.???.unit.defaultunit. > The question is, if all that is available in the modules namespace > somehow. But I guess so. We should try it. It would be a nice starting > point for writing a arg.tex like proposal on units ... I'm not quite sure, whether something like this would work, but however, this is IMHO not that important. Usually you just want one scali= ng of the units at any time.=20 Ok, to conclude this thread from my side, I would suggest that we drop unit in canvas pretty soon. Any objections? J=F6rg=20 |
From: Andre W. <Andre.Wobst@Physik.Uni-Augsburg.DE> - 2002-02-26 17:12:05
|
Hi, On 26.02.02, Joerg Lehmann wrote: > > It might be natural (I feel quite sure), that we then do have a globa= l > > unit variable. For the moment, we don't have it and therefore run int= o > > the troubles you talked about. We may know just decide, what to do. I > > would say, that it is ok. Even so, there is a way out by doing: >=20 > I also think, that we should do it like that and drop our present > scheme. It's really too complicated and the user gains not very much > from it. Yes. And it is just not necessary. However see note below. > > import pyx as pyx1 > > import pyx as pyx2 > >=20 > > Whenever you use now pyx1, you should be able to access the pyx1 > > global defaultunit, whereas you do the same within pyx2. I haven't > > tried it (have never done something like that), but hopefully this is > > possible. The key for doing so, is that the lineto for example doesn'= t > > just look for pyx.unit.defaultunit, but for self.???.unit.defaultunit. > > The question is, if all that is available in the modules namespace > > somehow. But I guess so. We should try it. It would be a nice startin= g > > point for writing a arg.tex like proposal on units ... >=20 > I'm not quite sure, whether something like this would work, but > however, this is IMHO not that important. Usually you just want one sca= ling > of the units at any time.=20 That's right, of course. And I would even think about locking the defaultunit after it's first use --- on the other side this might make problems, but I don't guess so. And it might create some overhead (what would be bad). However, I would like to see a locking. But what I really wanted to say is that I will try out that crap I wrote above. (BTW: it might be, that it is not even necessary to write something complicated like self.???.unit.defaultunit ... it might just work by default. I'll find that out.) The main point is, that we then would be able to *have* different units (what happens when mixing these things??? ... I also guess that that's might work without any problems) ... and at the same time have a default unit in each subsystem. I would like that quite a lot. > Ok, to conclude this thread from my side, I would suggest that we drop > unit in canvas pretty soon. Any objections? No. And we should not be worried if that "import as" doesn't work. It's not crucial. So just proceed ... Andr=E9 --=20 by _ _ _ Andre.Wobst@Physik.Uni-Augsburg.DE / \ \ / ) http://www.physik.uni-augsburg.de/~wobsta/ / _ \ \/\/ / watch a movie and learn about the mystery tippe top: (_/ \_)_/\_/ http://www.physik.uni-augsburg.de/~wobsta/tippetop/ |