From catherine.devlin at gmail.com Tue Dec 4 05:20:12 2007 From: catherine.devlin at gmail.com (Catherine Devlin) Date: Mon, 3 Dec 2007 23:20:12 -0500 Subject: [CentralOH] Dayton Dynamic Languages Users Group Message-ID: <6523e39a0712032020i3a2c3102sb202fb665a5c83a9@mail.gmail.com> Ohio Pythonistas, You wouldn't believe it. I stuck my hand in the Dayton Perl Mongers group, and this silvery weirdness enveloped them and they turned into a Python group. Well, not exactly. Actually, they've always been quite friendly to Python and Ruby content; as of last month, they decided their name ought to reflect that. http://www.dma.org/sigs.shtml#Dynamic It's as close as we're likely to see to a specific Python group in Dayton anytime soon, so I'm excited. I'll try to start making their meetings (I'd only made two so far.) If you're out here in the western part of our region, consider yourself invited! Actually, no matter where you are, consider coming to Dayton with a Python talk; we'd love to have you! It makes me think we should join with the Columbus Ruby brigade, etc. for a daylong all-dynamic-languages unconference in Columbus. Has anybody been to an unconference yet? I guess what's been holding me back, personally, is the feeling that I don't really know how to organize an unconference. To the extent that it needs organization; well, everything needs some organization. Anyway. Anybody else want to help make this happen? Dynamic language programmers of the world, unite; you have nothing to lose but your tedious typecasting boilerplate! Finally, if you're not spasming with excitement about PyCon yet, you should be. The talk submissions have been amazing. Wait till you see the schedule. -- - Catherine http://catherinedevlin.blogspot.com/ From mark at microenh.com Thu Dec 6 15:04:55 2007 From: mark at microenh.com (Mark Erbaugh) Date: Thu, 06 Dec 2007 09:04:55 -0500 Subject: [CentralOH] Python % Formatting Message-ID: <1196949895.5326.33.camel@P1900> I would like to be able to expand Python's % string formatting to include 'conditional' separators. My idea is that the text separating two fields would only be included in the output string if there were actually text on both sides of it. For example, consider formatting a person's name. The name consists of first, middle and last parts. Assume the data is supplied in a dictionary: name = {'first': 'Mark', 'middle' : 'E.', 'last': 'Erbaugh'} I can create an string of the name using: '%(first)s %(middle)s %(last)s' % name ==> 'Mark E. Erbaugh' Using the same data, I can create a name in the last, first format: '%(last)s, %(first)s %(middle)s' % name ==> 'Erbaugh, Mark E.' Suppose I have a person with no middle name. The resulting string would have two spaces between the first and last name. Similarly, if the person only has one name and it was stored in the 'last' field, it would print with two leading spaces. I'd like the routine to be able to get rid of these extraneous spaces. Another use for this would be in formatting of mailing addresses. Some addresses may have two address lines, some only the first. addr = {'line1' : '123 XYZ Street', 'line2' : 'Apt 12'} '%(line1)s\n%(line2)s' % addr If line2 is blank it would be nice to eliminate the separating '\n', so there would be no blank line in the address. Mark From gacsinger at gmail.com Thu Dec 6 17:37:30 2007 From: gacsinger at gmail.com (Greg Singer) Date: Thu, 6 Dec 2007 11:37:30 -0500 Subject: [CentralOH] Python % Formatting In-Reply-To: <1196949895.5326.33.camel@P1900> References: <1196949895.5326.33.camel@P1900> Message-ID: On Dec 6, 2007 9:04 AM, Mark Erbaugh wrote: > I would like to be able to expand Python's % string formatting to > include 'conditional' separators. My idea is that the text separating > two fields would only be included in the output string if there were > actually text on both sides of it. It's a neat idea, but it's easy enough to pass the resulting string through a filter to remove extraneous whitespace: import re filter=lambda s:re.sub(r'(\s){2,}',r'\1',s) #original example name = {'first': 'Mark', 'middle' : 'E.', 'last': 'Erbaugh'} print filter('%(first)s %(middle)s %(last)s' % name) # ==> Mark E. Erbaugh #no middle name name = {'first': 'Mark', 'middle' : '', 'last': 'Erbaugh'} print filter('%(first)s %(middle)s %(last)s' % name) # ==> Mark Erbaugh - Greg From bmintern at gmail.com Thu Dec 6 22:24:10 2007 From: bmintern at gmail.com (Brandon Mintern) Date: Thu, 6 Dec 2007 16:24:10 -0500 Subject: [CentralOH] Python % Formatting In-Reply-To: References: <1196949895.5326.33.camel@P1900> Message-ID: <4c0fccce0712061324o5576cedar7ebdc7b8d370427d@mail.gmail.com> I think I would probably end up using the .join() operator for this kind of thing. def name_string (name): return ', '.join([name['last']] \ + filter(None, [' '.join([name[x] \ for x in ('first', 'middle') \ if x in name])] >>> name_string(name) 'Erbaugh, Mark E.' >>> del name['middle'] >>> name_string(name) 'Erbaugh, Mark' >>> del name['first'] >>> name_string(name) 'Erbaugh' Of course, that looks ugly, but it could be wrapped up in some kind of function that would do it all for you: def formatter(items, format): delim = format[0] strings = [] for x in format[1:]: if type(x) is str: if x in items: strings.append(items[x]) else: fmt_str = formatter(items, x) if fmt_str: strings.append(fmt_str) return delim.join(strings) >>> name = {'first': 'Mark', 'middle' : 'E.', 'last': 'Erbaugh'} >>> formatter(name, (', ', 'last', (' ', 'first', 'middle'))) 'Erbaugh, Mark E.' >>> del name['middle'] >>> formatter(name, (', ', 'last', (' ', 'first', 'middle'))) 'Erbaugh, Mark' >>> del name['first'] >>> formatter(name, (', ', 'last', (' ', 'first', 'middle'))) 'Erbaugh' From catherine.devlin at gmail.com Thu Dec 6 23:01:52 2007 From: catherine.devlin at gmail.com (Catherine Devlin) Date: Thu, 6 Dec 2007 17:01:52 -0500 Subject: [CentralOH] Python % Formatting In-Reply-To: <4c0fccce0712061324o5576cedar7ebdc7b8d370427d@mail.gmail.com> References: <1196949895.5326.33.camel@P1900> <4c0fccce0712061324o5576cedar7ebdc7b8d370427d@mail.gmail.com> Message-ID: <6523e39a0712061401j79ba588rffd3dd4f5bd4192e@mail.gmail.com> Hmm, neat question, and good answers so far. I usually end up just doing something like '%s %s%s' % (firstName, ((middleName or '') and '%s ' % middleName), lastName) or, with the Python 2.5 syntax, '%s %s%s' % (firstName, (('%s ' % middleName) if middleName else ''), lastName) ... but, of course, neither of those is completely pretty. There are a bunch of templating engines that are great when the basic % interpolation just isn't enough. Cheetah is the one that comes to mind. I don't know it that well, so I can't actually say if there's a solution in there for you, but it's a good thing to try if built-in substitution isn't enough. As you can see, there's more than one way to do it! (Oops, wash my mouth out.) -- - Catherine http://catherinedevlin.blogspot.com/ From bmintern at gmail.com Thu Dec 6 23:24:35 2007 From: bmintern at gmail.com (Brandon Mintern) Date: Thu, 6 Dec 2007 17:24:35 -0500 Subject: [CentralOH] Python % Formatting In-Reply-To: <6523e39a0712061401j79ba588rffd3dd4f5bd4192e@mail.gmail.com> References: <1196949895.5326.33.camel@P1900> <4c0fccce0712061324o5576cedar7ebdc7b8d370427d@mail.gmail.com> <6523e39a0712061401j79ba588rffd3dd4f5bd4192e@mail.gmail.com> Message-ID: <4c0fccce0712061424g64891a2an810e121aad37c72c@mail.gmail.com> Upon defining my formatter operation, I realized it had a couple shortcomings that I have fixed in this new version. It now takes "format" as any iterable, and keys can include types such as int (instead of just str as before). Here's the new version. def formatter(items, format): """ formatter(items, format) A special purpose formatting function which takes items as a dictionary and format as an iterable where the first element in format is a delimiter and the rest of the elements are either keys into items or another iterable with the same structure. The return value is best illustrated with some examples: d = {'a': 'r', 'b': 's', 'c': 't'} formatter(d, (' ', 'a', 'b', 'c')) # 'r s t' formatter(d, (' ', 'a', 'b', 'd', 'c')) # 'r s t' formatter(d, (' ', 'a', (';', 'b', 'c'))) # 'r s;t' formatter(d, (' ', 'a', (';', 'b', 'c', (',', 'd', 'e')))) # 'r s;t' """ it = iter(format) try: delim = it.next() assert delim is str except (StopIteration, AssertionError): raise ValueError("1st element of format iterable" " must be delimiter of type str") strings = [] for x in it: if type(x) is not str: try: fmt_str = formatter(items, x) if fmt_str: # if result is an empty string, ignore it strings.append(fmt_str) continue except TypeError: # x must a key of another type, like int pass if x in items: strings.append(items[x]) return delim.join(strings) From bmintern at gmail.com Thu Dec 6 23:28:58 2007 From: bmintern at gmail.com (Brandon Mintern) Date: Thu, 6 Dec 2007 17:28:58 -0500 Subject: [CentralOH] Python % Formatting In-Reply-To: <4c0fccce0712061424g64891a2an810e121aad37c72c@mail.gmail.com> References: <1196949895.5326.33.camel@P1900> <4c0fccce0712061324o5576cedar7ebdc7b8d370427d@mail.gmail.com> <6523e39a0712061401j79ba588rffd3dd4f5bd4192e@mail.gmail.com> <4c0fccce0712061424g64891a2an810e121aad37c72c@mail.gmail.com> Message-ID: <4c0fccce0712061428m14257928oe256279389fead18@mail.gmail.com> Whoops, that assert statement should have been: assert type(delim) is str Sorry about that. From mark at microenh.com Fri Dec 7 17:08:25 2007 From: mark at microenh.com (Mark Erbaugh) Date: Fri, 07 Dec 2007 11:08:25 -0500 Subject: [CentralOH] Python % Formatting Message-ID: <1197043705.5338.8.camel@P1900> Thanks for the suggestions. I agree with Catharine that there is more than one way to do things, but I don't see anything wrong with that (at least in Python). As far as stripping the whitespace after the formatting, the problem is that sometimes the characters to be stripped aren't whitespace (i.e. commas) and sometimes the data may contain whitespace. You don't want to convert 'New York' to 'NewYork'. Join is a good idea, but require coding. I am looking for kind of a meta language definition. I like the dict/mapping capability of the % formatting. This makes it possible to feed data directly from a database to a print formatter. It opens the possibility of letting the user (who doesn't want to write Python code) define the output. Templating libraries are a good idea, but seems like it might be overkill for this situation. I worked up a solution, but last night after I thought it was finished it failed a new unit test case (yes, I like to do TDD), so I've got a little (hopefully) re-work. When I get it done, I'll post it here. Mark From mark at microenh.com Fri Dec 7 18:12:12 2007 From: mark at microenh.com (Mark Erbaugh) Date: Fri, 07 Dec 2007 12:12:12 -0500 Subject: [CentralOH] Python % Formatting Message-ID: <1197047532.5338.24.camel@P1900> Here is my first cut at some code to do what I want. I've added a couple of features that weren't in the original request, but should add some value. See the docstrings below for more information. Feedback is welcome! Mark =============================================================== import UserDict def split_fmt(fmt): """ split a partial format string into the format portion and any trailing characters. the format string includes all characters up to and including the first letter after the ')' split_fmt('first)2s.') -> ('first)2s', '.') if no formatting field is found return the input and '' """ p = fmt.find(')') if p > -1: l = len(fmt) p += 1 while p < l: if fmt[p].isalpha(): p += 1 return fmt[:p], fmt[p:] else: p +=1 return fmt, '' class csDict(UserDict.UserDict): """ user dict that returns '' if element not found """ def __getitem__(self, key): return self.data.get(key, '') def cs(fmt, data={}, **kwds): """ implement 'conditional' separator formatting. This expands the % mapping formatting. i.e. data = {'first': 'Mark', 'midle': 'E.', 'last': 'Erbaugh'} fmt = '%(first)s %(middle)s %(last)s' fmt % data -> 'Mark E. Erbaugh' This is the similar to 'normal' % dict formatting. Extensions to % mapping formatting if the field referenced does not exist or the data field is empty, that field and any characters follwing it are skipped. This does not apply to the last field. Any trailing characters or whitespace will be printed. If fields at the end are empty, the trailing characters or whitespace from the last non-empty field will be skipped Examples: FMT = '%(first)s %(middle)s %(last)s.' data(first, middle, last) 'Mark', '', 'Erbaugh' -> 'Mark Erbaugh.' (space after middle omitted) 'Mark', '', '', -> 'Mark.' (spaces after first and middle omitted, period after empty last kept) FMT = '%(last)s, %(first) %(middle).' data (first, middle, last) 'Mark', '', 'Erbaugh' -> 'Erbaugh, 'Mark.' '', '', 'Erbaugh -> 'Erbaugh.' comma after last ommited (no further non-blank fields) '', 'Edwin', 'Erbaugh -> 'Erbaugh, Edwin.' (space after first omitted) data can be a mapping(dict) or keyword parameters or both if a keyword parameter is the same as a dict key, the keyword parameter will overwrite the dict value """ def fmt_str(f): return ('%(' + f) % d d = {} d.update(data) d.update(kwds) d = csDict(d) r = [] r1 = fmt.split('%(') r.append(r1[0]) # first element will not have field to be formatted added_last = False for i in r1[1:-1]: f,t = split_fmt(i) if f > '': o = fmt_str(f) if o > '': r.append(o) r.append(t) added_last = True f,t = split_fmt(r1[-1]) o = fmt_str(f) if o == '' and added_last: del r[-1] else: r.append(o) r.append(t) return ''.join(r) From pythondevdang at lazytwinacres.net Sat Dec 8 13:39:38 2007 From: pythondevdang at lazytwinacres.net (Daniel 'Dang' Griffith) Date: Sat, 08 Dec 2007 07:39:38 -0500 Subject: [CentralOH] Python % Formatting In-Reply-To: References: Message-ID: <6.2.3.4.2.20071208073749.020694a8@mail.lazytwinacres.net> What are some other "use cases" for this, other than person names? I.e., when else might I need this function? --dang From mark at microenh.com Sun Dec 9 18:45:13 2007 From: mark at microenh.com (Mark Erbaugh) Date: Sun, 09 Dec 2007 12:45:13 -0500 Subject: [CentralOH] Python % Formatting Message-ID: <1197222314.5268.2.camel@P1900> I'm currently using it to provide formatting for mailing addresses as well as names. Basically, the database stores common address parts. The formatting is used to put those parts together in the proper order for the country. Mark From brian.costlow at gmail.com Mon Dec 10 14:49:14 2007 From: brian.costlow at gmail.com (Brian Costlow) Date: Mon, 10 Dec 2007 08:49:14 -0500 Subject: [CentralOH] Python % Formatting In-Reply-To: <1197222314.5268.2.camel@P1900> References: <1197222314.5268.2.camel@P1900> Message-ID: <89d8b1b00712100549g823051v9528a3bbc3ae5c96@mail.gmail.com> I can think of something I might be able to use it for. We're using Django for some of our work. Django models (their lightweight ORM mapper, for those unfamiliar with Django) use the __str__ function as a quick way to get a string representation of objects (db rows). It's used in their automatic admin system, and we have used it in a couple of places to display data in our own views. It works best where data from the same object will get displayed out as part of the same line with the same formatting (so it can all be stuffed into one template variable.) So if I have a model instance breakfast, Instead of : response['breakfast'] = "I had %s and %s eggs for breakfast", (breakfast.meat, breakfast.egg_type) I can just write response['breakfast'] = str(breakfast) Except that doesn't work so well when one of the fields for a particular instance is blank. You end up with: 'I had spam and eggs for breakfast' # extra space after and or worse 'I had and scrambled eggs for breakfast.' Using something like this, I could add the 'eggs' and the 'and' as string variable back in the model, and get a more intelligent string representation that I can use more often. 'I had %s %s %s %s for breakfast'. Not a too terrible violation of separation of concerns, (you can always access the fields directly if you need them) and it helps with DRY. Oh, and hello all, first time posting here. I'm part of a small group of folks doing process automation and the occasional web application for Vertis, a fairly large printing and communications company. We use Django and parts of Twisted on Linux, OS X and Solaris. We also do some legacy PHP and Perl stuff (that we're porting whenever we can make an ROI case). From jeff at taupro.com Thu Dec 13 09:07:05 2007 From: jeff at taupro.com (Jeff Rush) Date: Thu, 13 Dec 2007 02:07:05 -0600 Subject: [CentralOH] New Types In-Reply-To: <200706131722.32954.david.car@earthlink.net> References: <200706131722.32954.david.car@earthlink.net> Message-ID: <4760E829.1080707@taupro.com> David Car wrote: > > I have a question about new types in Python. Just finished reading up and > trying a few things out, but I'm a little confused about one thing. When > declaring a new type, we basically have two new structures. One is the per > instance structure (your PyObject structure), which is basically an expansion > of the PyObject structure. At the beginning of that structure is the macro > declaration of PyObject_HEAD which contains the reference counter and a > pointer to the new type which is a structure of _typeobject. Then for your > new type (i.e. your _typeobject structure) there is a place holder for the > size of your per instance PyObject structure along with all the necessary > function pointers your new type will support. > My question is this: > Where and when does the pointer in your per instance PyObject > structure get set? How does the interpreter know that your > PyObject structure is related to your PyTypeObject structure? > Since your PyObject structure naming convention is not tied > to your PyTypeObject name, how are the two associated? The connection and allocation occurs in the __new__ class method, which in your code looks like: (much detail omitted for readability) typedef struct { /* instance structure */ PyObject_HEAD; char *cardname; } alsapcm_t; static PyTypeObject ALSAPCMType; /* type structure */ alsapcm_new(...) { /* allocates and initializes an instance */ alsapcm_t *self = PyObject_New(alsapcm_t, &ALSAPCMType); return self; } There are some good comments in the file: /usr/include/python2.4/objimpl.h > I see how > your type is statically instantiated in the initialization, but I don't see > where your per instance PyObject is related to it? Is it simply that the two > structures co-exist in the same module? No magic. BTW, if you are interested in the C aspects of Python like this one, you ought to check out the mailing list "CAPI-SIG", at: http://mail.python.org/mailman/listinfo/capi-sig It was created to keep C discussions off of the comp.lang.python list where many folks only know Python anyway. Your question re linking instance and type is a very good one though. -Jeff (Dallas Pythoneer, but helping out where I can) From jeff at taupro.com Thu Dec 13 09:09:03 2007 From: jeff at taupro.com (Jeff Rush) Date: Thu, 13 Dec 2007 02:09:03 -0600 Subject: [CentralOH] New Types In-Reply-To: <200706131722.32954.david.car@earthlink.net> References: <200706131722.32954.david.car@earthlink.net> Message-ID: <4760E89F.7030707@taupro.com> David Car wrote: > > I have a question about new types in Python. Oops, I just realized how old that post was (5-mos) - sorry for replying to stale threads. -Jeff From david.car7 at gmail.com Fri Dec 14 13:48:50 2007 From: david.car7 at gmail.com (David Car) Date: Fri, 14 Dec 2007 07:48:50 -0500 Subject: [CentralOH] New Types In-Reply-To: <4760E89F.7030707@taupro.com> References: <200706131722.32954.david.car@earthlink.net> <4760E89F.7030707@taupro.com> Message-ID: <37f7fbce0712140448hf10316dw8b663aa0d794e24d@mail.gmail.com> Jeff, Thanks a bunch. I know it was stale, but I still appreciate it and I never got a sufficient answer from other sources. Thanks for the additional sources. All the best. -David On 12/13/07, Jeff Rush wrote: > > David Car wrote: > > > > I have a question about new types in Python. > > Oops, I just realized how old that post was (5-mos) - sorry for replying > to > stale threads. > > -Jeff > > -- Regards, David -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.python.org/mailman/private/centraloh/attachments/20071214/dd93e580/attachment.htm