Re: Tkinter.event.widget: handler gets name instead of widget.
On Sat, 2012-07-14 at 20:10 -0700, rantingrickjohn...@gmail.com wrote: On Thursday, July 12, 2012 1:53:54 PM UTC-5, Frederic Rentsch wrote: The hit list is a table of investment titles (stock, funds, bonds) that displays upon entry of a search pattern into a respective template. The table displays the matching records: name, symbol, ISIN, CUSIP, Sec. Any line can be click-selected. So they are to look like buttons. Hmm. If they appear like a button widget anyway, then why not just use a button widget? Why indeed? Why does one do simple things in a complicated way? Stations on the sinuous path the explorer takes surveying unknown territory, I guess. Your example below is just what I need. Thanks! Representing the mentioned names and id codes in Label widgets was the simplest way I could come up with to align them in columns, admittedly without the benefit of much experience. But it does look good. the layout is fine. But is it really the simplest? :) ## START CODE ## import Tkinter as tk from Tkconstants import * colWidths = (5,10,30,5) N_COLS = len(colWidths) N_ROWS = 6 root = tk.Tk() for r in range(N_ROWS): # Create some imaginary text to display in each column. # Also try using string methods center and rjust to # see alternative justification of text. lst = [str(r).ljust(colWidths[r]) for r in range(N_COLS)] b=tk.Button(root, text=''.join(lst)) b.pack(padx=5, pady=5) root.mainloop() ## END CODE ## You could easily expand that into something reusable. Now. If you need to place fancy borders around the texts, or use multiple fonts, or use images, or blah blah blah... then you may want to use the canvas items provided by the Tkinter.Canvas widget INSTEAD of buttons. With the canvas, you can create a simple rectangle (canvas.create_rectangle) that represents a button's outside dimension and give it a button styled border. Then you can bind click events to mimic the button press action. Then you can place canvas_text items on top of that fake button and configure them to be invisible to click events. These text items will not interfer like the Tkinter.Label widgets are currently doing. However, i would suggest the Tkinter.Button solution is the easiest by far. I find the Tkinter system quite challenging. Doing a layout isn't so much a matter of dimensioning and placing things as a struggle to trick a number of automatic dimensioning and placing mechanisms into obliging--mechanisms that are rather numerous and hard to remember. I don't think i agree with that assessment. Sticky, justify, side, anchor, width, height, pad, ipad . . . a plethora of similar formatting concepts with applicability, precedence and effect rules that are certainly easy to work with once one knows them inside out. Until such time it's much trial-and-error, and reading of course, which also frequently involves guessing what is meant and cross-checking by experiment. For instance, I had to find a way to control the size of frames. The geometry mangers deflate everything bottom to top and utterly ignore width and height specifications unless the widget is empty. The solution I found was spanners, frames slimmed down to zero whose length acts as a foot in the door of their parent, as it were. I suspect there are better ways. ## START TANGENTIAL MEANDERINGS ## I find the geometry management of Tkinter to be quite powerful whilst being simultaneously simplistic. You only have three main types of management: Grid, Place, and Pack. Each of which has a very specific usage. One caveat to know is that you can NEVER mix Grid and Pack in the same container widget! I find myself using grid and pack the most, with grid being at the top of the list. Now, i will agree that grid can be confusing at first until you understand how to rowconfigure and columnconfigue the containing widget (be it a frame or a toplevel). There is also the sticky attribute to consider. ## END TANGENTIAL MEANDERINGS ## Thanks for the reminder. But all in all, i would say the most difficult part of the Tkinter geometry management API is coming to grips as to which of the three geometry managers is the best choice for the particular problem at hand -- and you will find yourself using more than one manager in a single GUI app! But i don't see you solving this problem by stacking one widget on another. I believe it's time to seek out a new solution. I agree. Your idea of using pre-formatted text in buttons is definitely the way to go. EASY: Using rows of Tkinter.Button coupled with a per-formatted text string. ADVANCED: Creating pseudo buttons on a canvas and stacking text objects (or whatever you like) on them. I'll keep that in mind. Finally I can report that I found the error I started this thread with. (Attribute 'widget' of an event was type str) I have a Frame Data as a container of all sorts
Re: Tkinter.event.widget: handler gets name instead of widget.
On Tue, 2012-07-10 at 15:11 -0700, Rick Johnson wrote: I've tried to condense your code using the very limited info you have provided. I have removed unnecessarily configuring of widgets and exaggerated the widget borders to make debugging easier. Read below for QA. ## START CONDENSED CODE ## records = range(4) CNF_SUBFRAME = { 'bd':5, # rowFrame boder width. 'relief':RIDGE, } CNF_LABEL = { 'anchor':W, 'width':10, 'bg':'gray', } class FooFrame(tk.Frame): def __init__(self, master, **kw): tk.Frame.__init__(self, master, **kw) self.build_records() def build_records(self): # Should this method be called by __init__??? # Not sure if records is passed-in or global??? for n in range(len(records)): record = records[n] rowFrame = tk.Frame(self, name='-%d-'%n, **CNF_SUBFRAME) rowFrame.bind ('Enter', self.evtEnter) rowFrame.bind ('Leave', self.evtLeave) rowFrame.bind ('ButtonRelease-1', self.evtButtonOneRelease) rowFrame.bind ('ButtonRelease-3', self.evtButtonThreeRelease) rowFrame.grid (row=n+2, column=1, padx=5, pady=5) for i in range(4): lbtext = 'Label_'+str(i) label = tk.Label(rowFrame, text=lbtext, **CNF_LABEL) label.grid (row=0, column=i, sticky=NW) def evtEnter(self, event): w = event.widget print 'evtEnter', w.winfo_class() w.config(bg='magenta') def evtLeave(self, event): w = event.widget print 'evtLeave', w.winfo_class() w.config(bg='SystemButtonFace') def evtButtonOneRelease(self, event): w = event.widget print 'evtButtonOneRelease', w.winfo_class() w.config(bg='Green') def evtButtonThreeRelease(self, event): w = event.widget print 'evtButtonThreeRelease', w.winfo_class() w.config(bg='Blue') if __name__ == '__main__': root = tk.Tk() frame = FooFrame(root, width=100, height=100, bg='red', bd=1) frame.pack(padx=5, pady=5) root.mainloop() ## END CONDENSED CODE ## In the code sample provided, you will see that the label widgets stacked on each row will block click events on the containing rowFrames below them. You can get a click event (on the sub frames) to work by clicking the exaggerated border on the frames. All the events work properly for me, although this GUI interface seems unintuitive even with proper borders and colors. Fredric, I can't help but feel that you are not attacking the problem correctly. Please explain the following questions in detail so that i may be able to provide help: It works for me too. I spent another day running the offending class in a simplified environment and it worked flawlessly. In what way the environment makes the difference is anything but obvious. But it has got to be the environment. Q1. You have subclassed a Tkinter.Frame and you are building rows of sub-frames into this toplevel frame; with each row holding horizontally stacked label widgets. Okay, I can see a need to wrap up a RowFrame object, but i don't see a need to create a RowFrameFactory. Can you explain this design decision? I sent this same response yesterday with a screen shot attached. The message didn't pass. It must have been rejected by a spam filter. So I try again without the screen shot. (Too bad. A picture is worth a thousand words). The hit list is a table of investment titles (stock, funds, bonds) that displays upon entry of a search pattern into a respective template. The table displays the matching records: name, symbol, ISIN, CUSIP, Sec. Any line can be click-selected. So they are to look like buttons. Representing the mentioned names and id codes in Label widgets was the simplest way I could come up with to align them in columns, admittedly without the benefit of much experience. But it does look good. the layout is fine. I find the Tkinter system quite challenging. Doing a layout isn't so much a matter of dimensioning and placing things as a struggle to trick a number of automatic dimensioning and placing mechanisms into obliging--mechanisms that are rather numerous and hard to remember. Q2. It seems odd to me that you want to engage the rowFrame widgets via events but NOT the Label widgets. Can you explain this design decision? Again, the labels serve to align the fields into columns. As to the bindings, I just now found out, that Entry and Leave can be bound to the line frame, but the mouse buttons don't act on the frame with the labels covering it wall to wall. Entry will lighten up the background of the line. Leave restores the normal color. ButtonRelease-N will select the line, darkening the text. The coloring has to be done separately on each label across the line, as the labels cover the frame. That isn't a problem. I'm sorry
Re: Tkinter.event.widget: handler gets name instead of widget.
On Fri, 2012-07-13 at 09:26 +0200, Peter Otten wrote: Frederic Rentsch wrote: I'm sorry I can't post an intelligible piece that does NOT work. I obviously can't post the whole thing. How about a pastebin then? Or even bitbucket/github as you need to track changes anyway? It is way too convoluted. Convoluted code is much easier to debug than no code ;) Another random idea: run your code on a more recent python/tcl installation. If you are lucky you get a different error. So many good ideas! I can hardly keep up. Let me try anyway. I hesitate to ask dumb questions, but I guess I have to. What is python/tcl? I enlisted Google, Synaptic, apt-cache, apt-get, dpkg and scouring the profusion I couldn't detect any actionable piece of information, undoubtedly due to my modest expertise in matters of system administration. I next spent a day with an attempt to upgrade to Python 2.7.3, figuring that that might simultaneously take care of upgrading tcl. Accustomed to installing packages I had to venture into the unknown territory of compiling source, because no package was available. (Windows, Apple, yes. Linux, no). The compile went smoothly, but ended like this: ... build finished, but the necessary bits to build these modules were not found: _bsddb _curses _curses_panel _sqlite3 _ssl _tkinter bsddb185 bz2 dbm gdbm readline sunaudiodev To find the necessary bits, look in setup.py in detect_modules() for the module's name. I didn't know what to look for in setup.py, spent a couple of hours turning stones and encountered evidence of a bunch of missing header files, probably of other modules which I had installed rather than compiled. 2.7.3 came up in terminals, but not in an IDLE window. No wonder, _tkinter was reported not found; and so many others with it that, anxious to get on, I stopped venturing further into this labyrinth, erased everything 2.7.3 and now I'm back to 2.6 and would greatly appreciate advice on upgrading python/tcl. I shall look at pastebin and bitbucket/github right away. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Tkinter.event.widget: handler gets name instead of widget.
On Tue, 2012-07-10 at 18:06 -0700, Rick Johnson wrote: Also: Q3: Why are you explicitly setting the name of your subFrame widgets instead of allowing Tkinter to assign a unique name?...AND are you aware of the conflicts that can arise from such changes[1]? I find custom-named widgets easier to work with during development. I can tell what this is; .main-frame.data-frame.title-hit-list.-10-. If I didn't assign names it would look something line this:.2837029.283725.283762.2848308. Once my program works I can drop custom-naming. I understand that conflicts may arise if one assigns numeric names. To find out whether the digits in the label names ('-10-' above) might be implicated, I changed to spelled-out names ('ten'). The change had no effect. The reference you list blow (x147-more-on-widget-names.htm) indeed says don't use names which only contain digits. Q4: Are you aware of the built-in function enumerate[2]? I see you are passing around indexes to iterables AND simultaneously needing the obj reference itself. I prefer to keep indexing to a minimum. If there is no bleeding edge performance issue to worry about (and there almost *always* never is) why not use enumerate? Aware, yes. In the habit of, no. Thanks for the reminder. [1] http://www.pythonware.com/library/tkinter/introduction/x147-more-on-widget-names.htm [2] http://docs.python.org/release/3.0.1/library/functions.html#enumerate Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Tkinter.event.widget: handler gets name instead of widget.
On Mon, 2012-07-09 at 10:49 -0700, Rick Johnson wrote: On Jul 9, 12:58 am, Terry Reedy tjre...@udel.edu wrote: When posting problem code, you should post a minimal, self-contained example that people can try on other systems and versions. Can you create the problem with one record, which you could give, and one binding? Do you need 4 fields, or would 1 'work'? I'll firmly back that sentiment. Fredric, if you cannot get the following simple code events to work properly, then how do you think you can get events working properly on something more complex? ## START CODE ARTISTRY ## import Tkinter as tk from Tkconstants import * class MyFrame(tk.Frame): def __init__(self, master, **kw): tk.Frame.__init__(self, master, **kw) self.bind('Enter', self.evtMouseEnter) self.bind('Leave', self.evtMouseLeave) self.bind('Button-1', self.evtButtonOneClick) def evtMouseEnter(self, event): event.widget.config(bg='magenta') def evtMouseLeave(self, event): event.widget.config(bg='SystemButtonFace') def evtButtonOneClick(self, event): event.widget.config(bg='green') if __name__ == '__main__': root = tk.Tk() for x in range(10): f = MyFrame(root, height=20, bd=1, relief=SOLID) f.pack(fill=X, expand=YES, padx=5, pady=5) root.mainloop() ## END CODE ARTISTRY ## This works perfectly well! What makes the case difficult is an exceptional misbehavior for no apparent reason. If I manage to strip the critical section of environmental details in the interest of concision and legibility and still reproduce the error I shall post it. So far I have failed: the stripped model I distilled yesterday worked fine. --- More points to ponder: --- 1. Just because the Tkinter designers decided to use idiotic names for event sequences does not mean you are required to blindly follow their bad example (the whole: if johnny jumps off a cliff..., thing comes to mind) 2. I would strongly recommend you invest more thought into your event handler identifiers. ALL event handlers should marked as *event handlers* using a prefix. I like to use the prefix evt. Some people prefer other prefixes. In any case, just remember to be consistent. Also, event handler names should reflect WHAT event they are processing, not some esoteric functionality of the application like pick_record or info_profile. However if you like, simply have the event handler CALL an outside func/meth. This type of consistency is what separates the men from the boys. 3. The Python Style Guide[1] frowns on superfluous white space (be it horizontal OR vertical!) I would strongly recommend you read and adapt as much of this style as you possibly can bear. Even if we don't all get along, it IS *very* important that we structure our code in a similar style. [1] http://www.python.org/dev/peps/pep-0008/ Excellent suggestions. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Tkinter.event.widget: handler gets name instead of widget.
On Mon, 2012-07-09 at 01:58 -0400, Terry Reedy wrote: On 7/8/2012 5:19 PM, Frederic Rentsch wrote: Hi widget wizards, The manual describes the event attribute widget as The widget which generated this event. This is a valid Tkinter widget instance, not a name. This attribute is set for all events. Same in 3.3, with nice example of using it. def turnRed(self, event): event.widget[activeforeground] = red self.button.bind(Enter, self.turnRed) Ans so it is--has been until on the latest occasion event.widget was not the widget, but its name, crashing the handler. Has event.widget been the widget only in other programs or previously with the same program? I bind Enter to Frames, each Frame calling the same handler that is supposed to change the background color. It is the Enter action that generates the event. No later the handler receives the event whose attribute widget is the widget's name (full path). My code doesn't create events anywhere. I suppose events vanish when the last handler terminates. . . . When posting problem code, you should post a minimal, self-contained example that people can try on other systems and versions. Attempting to strip the critical code, throwing out everything incidental to the problem so I could post something intelligible, I failed to fail: the bare essentials work. The problem appears to be in the incidental. Can you create the problem with one record, which you could give, and one binding? Do you need 4 fields, or would 1 'work'? It fails even with the Frame containing no Labels at all, like this: for n, record in enumerate(records): line_frame = Frame (self, name = _verbalize_number (n), width = 600, height = 20, relief = RAISED, **BUTTON_FRAME_) line_frame.bind ('Enter', self.enter) ## No Labels at all: ## for i in self.range_n_fields: ## field = Label (line_frame, text = record [self.INDICES [i]], anchor = W, width = self.COLUMN_WIDTHS [i], **DB_LIST_LABEL_) ## field.grid (row = 0, column = i, sticky = NW) def enter (self, event): w = event.widget print 'hit list.enter (). Event, widget', event, w, w.__class__ w.config (bg = ENTERED_BG_COLOR) hit list.leave (). Event, widget Tkinter.Event instance at 0xa52c60c .main-frame.data-frame.title-hit-list.one-zero type 'str' Exception in Tkinter callback Traceback (most recent call last): File /usr/lib/python2.6/lib-tk/Tkinter.py, line 1413, in __call__ return self.func(*args) File /home/fr/python/finance/piam/hit_list.py, line 114, in enter w.config (bg = ENTERED_BG_COLOR) AttributeError: 'str' object has no attribute 'config' _verbalize_number spells out the line numbers, because the manual says something about digits being reserved for the auto-generated widget names. I thought that assigned names containing digits might be a problem, but it wasn't. The dictionary arguments, by the way, are just style elements: colors, fonts, reliefs, etc. nothing functionally essential. # Dell E6500, Ubuntu 10.04, Python 2.6 You might try a current Python release, and the latest tcl/tk 8.5.11 released last March (comes with 3.3.0 Windows release, don't know how on Ubuntu). There might be (have been?) a bug with events on Frames, or on Frames within Frames treated as widgets. -- Terry Jan Reedy Terry, I interspersed a couple of answers above. As to your last suggestion I got Python 2.7.3 and managed to compile it. I would have preferred something ready to install, but that doesn't seem to be available for Linux. The compile went smoothly. But it'll take me another day to reorganize, beginning with the Applications menu which still shows IDLE (Python 2.6), while terminals already call the new version 2.7.3, but it doesn't know where MySQLdb is, and possibly where other things are. So for now I can't report on this effort either. But I certainly appreciate your help. Many thanks. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Tkinter.event.widget: handler gets name instead of widget.
On Mon, 2012-07-09 at 10:49 -0700, Rick Johnson wrote: On Jul 9, 12:58 am, Terry Reedy tjre...@udel.edu wrote: When posting problem code, you should post a minimal, self-contained example that people can try on other systems and versions. Can you create the problem with one record, which you could give, and one binding? Do you need 4 fields, or would 1 'work'? I'll firmly back that sentiment. Fredric, if you cannot get the following simple code events to work properly, then how do you think you can get events working properly on something more complex? ## START CODE ARTISTRY ## import Tkinter as tk from Tkconstants import * class MyFrame(tk.Frame): def __init__(self, master, **kw): tk.Frame.__init__(self, master, **kw) self.bind('Enter', self.evtMouseEnter) self.bind('Leave', self.evtMouseLeave) self.bind('Button-1', self.evtButtonOneClick) def evtMouseEnter(self, event): event.widget.config(bg='magenta') def evtMouseLeave(self, event): event.widget.config(bg='SystemButtonFace') def evtButtonOneClick(self, event): event.widget.config(bg='green') if __name__ == '__main__': root = tk.Tk() for x in range(10): f = MyFrame(root, height=20, bd=1, relief=SOLID) f.pack(fill=X, expand=YES, padx=5, pady=5) root.mainloop() ## END CODE ARTISTRY ## --- More points to ponder: --- 1. Just because the Tkinter designers decided to use idiotic names for event sequences does not mean you are required to blindly follow their bad example (the whole: if johnny jumps off a cliff..., thing comes to mind) 2. I would strongly recommend you invest more thought into your event handler identifiers. ALL event handlers should marked as *event handlers* using a prefix. I like to use the prefix evt. Some people prefer other prefixes. In any case, just remember to be consistent. Also, event handler names should reflect WHAT event they are processing, not some esoteric functionality of the application like pick_record or info_profile. However if you like, simply have the event handler CALL an outside func/meth. This type of consistency is what separates the men from the boys. 3. The Python Style Guide[1] frowns on superfluous white space (be it horizontal OR vertical!) I would strongly recommend you read and adapt as much of this style as you possibly can bear. Even if we don't all get along, it IS *very* important that we structure our code in a similar style. [1] http://www.python.org/dev/peps/pep-0008/ Rick, Thanks for your remarks. I spent most of the day working with Terry's input. And now I am falling asleep. So I shall study your inspirations tomorrow. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Tkinter.event.widget: handler gets name instead of widget.
Hi widget wizards, The manual describes the event attribute widget as The widget which generated this event. This is a valid Tkinter widget instance, not a name. This attribute is set for all events. Ans so it is--has been until on the latest occasion event.widget was not the widget, but its name, crashing the handler. # Here I build a list of selectable records having each four fields. # The fields are labels. The selectable line is a frame containing the # labels side by side. The line frames go into self, which is a Frame. for n in range (len (records)): record = records [n] line_frame = Frame (self, name = '-%d-' % n, relief = RAISED, **BUTTON_FRAME_) line_frame.bind ('Enter', self.enter) line_frame.bind ('Leave', self.leave) line_frame.bind ('ButtonRelease-1', self.pick_record) line_frame.bind ('ButtonRelease-3', self.info_profile) line_frame.grid (row = n+2, column = 1) for i in self.range_n_fields: # (0, 1, 2, 3) field = Label (line_frame, text = record [self.INDICES [i]], anchor = W, width = self.COLUMN_WIDTHS [i], **DB_LIST_LABEL_) field.grid (row = 0, column = i, sticky = NW) # Here is the Enter handler: def enter (self, event): w = event.widget print 'hit list.enter (). Event, widget', event, w, w.__class__ # Tracing line w.config (bg = SELECTED_BG_COLOR) # And here is what comes out. The first line is my tracing line. The name is correct in that it # names the entered line_frame, but is wrong because it should be the line_frame, not its name. # The rest is the red exception message: hit list.enter (). Event, widget Tkinter.Event instance at 0x9115dcc .main-frame.data-frame.title-hit-list.-10- type 'str' Exception in Tkinter callback Traceback (most recent call last): File /usr/lib/python2.6/lib-tk/Tkinter.py, line 1413, in __call__ return self.func(*args) File /home/fr/python/finance/piam/hit_list.py, line 83, in enter w.config (bg = SELECTABLE_BG_COLOR) AttributeError: 'str' object has no attribute 'config' # The same thing happens with Leave. The other handlers I haven't done yet. The same bindings work well in # a Menu class with the difference that the bindings are on the Labels, not a containing Frame. # Dell E6500, Ubuntu 10.04, Python 2.6 Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Tkinter binding question
On Tue, 2012-06-19 at 19:19 -0700, rantingrickjohn...@gmail.com wrote: On Tuesday, June 19, 2012 10:55:48 AM UTC-5, Frederic Rentsch wrote: If I copy your event descriptors into my program, the button-release callback still fails. It works in your code, not in mine. Here is what my code now looks like. It is somewhat more complicated than yours, because I bind Frames holding each a line (line_frame) and each frame contains a few Labels side by side. The idea is to achieve a table with vertically aligning columns each line of which I can click-select. (Is there a better way?) for line_frame in ...: line_frame.bind ('Enter', self.color_selected) line_frame.bind ('Leave', self.color_selectable) line_frame.bind ('ButtonRelease-1', self.pick_record) line_frame.bind ('ButtonRelease-3', self.info_profile) line_frame.grid (row = n+1, column = 0) for i in self.range_n_fields: field = Label (line_frame, width = ..., text = ... field.grid (row = 0, column = i, sticky = W) ... def color_selected (self, event): print 'hit list.color_selected ()' def color_selectable (self, event): print 'hit list.color_selectable ()' def pick_record (self, event): # Nver gets called print 'hit list.pick_record ()' def info_profile (self, event):# Never gets called print 'hit list.info_profile ()' Events only fire for the widget that currently has focus. Frames, labels, and other widgets do not receive focus simply by hovering over them. You can set the focus manually by calling w.focus_set() -- where w is any Tkinter widget. I can't be sure because i don't have enough of your code to analyze, but I think you should bind (either globally or by class type) all Enter events to a callback that sets the focus of the current widget under the mouse. Experiment with this code and see if it is what you need: ## START CODE ## from __future__ import print_function import Tkinter as tk def cb(event): print(event.widget.winfo_class()) event.widget.focus_set() root = tk.Tk() root.geometry('200x200+20+20') for x in range(10): w = tk.Frame(root, width=20, height=20,bg='red') w.grid(row=x, column=0, padx=5, pady=5) w = tk.Frame(root, width=20, height=20,bg='green', highlightthickness=1) w.grid(row=x, column=1, padx=5, pady=5) w = tk.Button(root, text=str(x)) w.grid(row=x, column=2, padx=5, pady=5) root.bind_all(Enter, cb) root.mainloop() ## END CODE ## You will see that the first column of frames are recieving focus but you have no visual cues of that focus (due to a default setting). In the second column you get the visual cue since i set highlightthicness=1. The third column is a button widget which by default has visual focus cues. Is this the problem? Yes, I was unaware of focus control. I understand that it is set either by a left mouse button click or the method focus_set (). PS: Also check out the w.bind_class() method. Incidentally, my source of inspiration for chaining event descriptors was the New Mexico Tech Tkinter 8.4 reference, That's an excellent reference BTW. Keep it under your pillow. Effbot also has a great tutorial. Thanks for this additional load af advice. Googling I chanced on an excellent introduction Thinking in Tkinter by Stephen Ferg. (http://www.ferg.org/thinking_in_tkinter/all_programs.html). He sets out identifying a common problem with tutorials: The problem is that the authors of the books want to rush into telling me about all of the widgets in the Tkinter toolbox, but never really pause to explain basic concepts. They don't explain how to think in Tkinter. He then explains seventeen functionalities, one at a time, and illustrates them with a little piece of code ready to run. Working through the examples is a good way to acquire a basic understanding without falling victim to brain clutter. I shall go through the examples very attentively and go on from there. Thanks again Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Tkinter binding question
Rick, Thank you for your thorough discussion. I tried your little program. Enter and leave work as expected. Pushing mouse buttons call leave-enter, exactly as it happened with my code. So that seems to be a default behavior. No big deal. Without the tracing messages it would go unnoticed. Releasing either of the bound mouse buttons displays the corresponding messages. So all works fine. If I copy your event descriptors into my program, the button-release callback still fails. It works in your code, not in mine. Here is what my code now looks like. It is somewhat more complicated than yours, because I bind Frames holding each a line (line_frame) and each frame contains a few Labels side by side. The idea is to achieve a table with vertically aligning columns each line of which I can click-select. (Is there a better way?) for line_frame in ...: line_frame.bind ('Enter', self.color_selected) line_frame.bind ('Leave', self.color_selectable) line_frame.bind ('ButtonRelease-1', self.pick_record) line_frame.bind ('ButtonRelease-3', self.info_profile) line_frame.grid (row = n+1, column = 0) for i in self.range_n_fields: field = Label (line_frame, width = ..., text = ... field.grid (row = 0, column = i, sticky = W) ... def color_selected (self, event): print 'hit list.color_selected ()' def color_selectable (self, event): print 'hit list.color_selectable ()' def pick_record (self, event): # Nver gets called print 'hit list.pick_record ()' def info_profile (self, event):# Never gets called print 'hit list.info_profile ()' I admit that I don't have an accurate conception of the inner workings. It's something the traveler on the learning curve has to acquire a feel for by trial and error. In this case the differing behavior should logically have to do with the structural difference: I bind Labels that contain Labels. If I click this nested assembly, who gets the event? The contained widget, the containing widget or both? Frederic Incidentally, my source of inspiration for chaining event descriptors was the New Mexico Tech Tkinter 8.4 reference, which says: ... In general, an event sequence is a string containing one or more event patterns. Each event pattern describes one thing that can happen. If there is more than one event pattern in a sequence, the handler will be called only when all the patterns happen in that same sequence ... Again, predicting the precedence with overlaps is much like solving a murder case: finding suspects and let the innocent ones off the hook. The only reference I have found on that topic is in effbot.org's tkinterbook, which says that precedence goes to the closest match, but doesn't explain how one evaluates closeness. -- http://mail.python.org/mailman/listinfo/python-list
Tkinter binding question
Hi All, For most of an afternoon I've had that stuck-in-a-dead-end feeling probing to no avail all permutations formulating bindings, trying to make sense of manuals and tutorials. Here are my bindings: label_frame.bind ('Enter', self.color_selected) label_frame.bind ('Leave', self.color_selectable) label_frame.bind ('Button-1ButtonRelease-1', self.pick_record) label_frame.bind ('Button-3ButtonRelease-3', self.info_profile) Enter and Leave work fine. But when I try to select an entered item, the moment I push the left or the right button, color_selectable () and color_selected () are called again in rapid succession. The same effect happens even when I push the middle mouse button which is rather weird, because it has no binding. The behavior suggests that no event can occur on an entered widget before it is left again and if an event other that Leave comes in, the Leave callback gets called automatically. That can't be right, though. It isn't possible to click an item without entering it. I put traces in all of the four callbacks. So I know what gets called an what doesn't. Traces are: On Enter: hit list.color_selected () On Leave: hit list.color_selectable () Fine so far. Enter: hit list.color_selected ()# Still fine Button-1 or Button-2 or Button-3: hit list.color_selectable () # Not so fine! hit list.color_selected () ButtonRelease-1 (or -2 or -3) (nothing) Thanks for any suggestion Frederic OS: Ubuntu 10.04 LTS Python: sys.version: 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) [GCC 4.4.3] Tkinter: VERSION 73770 (help (Tkinter), last line) -- http://mail.python.org/mailman/listinfo/python-list
tkinter: is there a way to switch a widget's master?
Hi there, I would like to prepare a bunch of info text widgets to be displayed in Toplevel windows at the user's command (when ever he needs directions). I know how to remove and restore widgets without destroying them in between. The problem with a Toplevel is that it is a master that comes and goes, of a Text that is supposed to stay as long as the program runs. (Building the Text involves reading a file and compiling lots of edited-in formatting symbols. Repeating this every time the Toplevel is called seems rather inelegant.) toplevel = Toplevel (root, ...) info_text = MyText (toplevel, ...) info_text.pack () # No problem, except for the inelegant remake of the text on every call. I tried: text = MyText (root, ...) # Later, on user demand toplevel = Toplevel (root, ...) info_text.lower (belowThis = toplevel) info_text.pack () This doesn't work! toplevel is empty and text appears in the root window. Is there a way to switch a widget's master? Thanks for comments Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Tkinter: IDLE can't get out of mainloop
On Sat, 2012-03-31 at 06:29 -0400, Terry Reedy wrote: On 3/31/2012 3:42 AM, Frederic Rentsch wrote: Hi all, Is is a bad idea to develop Tkinter applications in IDLE? I understand that IDLE is itself a Tkinter application, supposedly in a mainloop and mainloops apparently don't nest. In standard configuration, one process runs IDLE, another runs user code, including tkinter code. So there should be no interference. The example in the tkinter doc runs from IDLE edit window on my system. The revised example in coming releases works even better. There have been several IDLE bugs fixed in the last few months, and even more since 2.6 before that. Upgrade if you can to get fixes, suffer the bugs since fixed, or patch your 2.6 installation. -- Terry Jan Reedy Terry, It helps to know that an upgrade might improve things. Thank you for the suggestion. And thanks also to Chris for his remark on .pyc files. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Tkinter: IDLE can't get out of mainloop
Hi all, Is is a bad idea to develop Tkinter applications in IDLE? I understand that IDLE is itself a Tkinter application, supposedly in a mainloop and mainloops apparently don't nest. I tried to install a root-destroy-protocol: def destroy_root (): print 'Destroying root' root.destroy () root.protocol (WM_DELETE_WINDOW, destroy_root) I see the tracing message 'Destroying root', but stay stuck unable to get the IDLE prompt back. Ctr-C doesn't work. The only way out I know is killing IDLE. When I do, a warning says that a program is still running. That must be IDLE's own WM_DELETE_WINDOW protocol. Is there a way to get the prompt back without killing IDLE? Is there a way to nest a mainloop? Up to now I have been able to get by without a mainloop. I suppose this is because I have only been doing layouts. Starting now to do events I observe what in the absence of a mainloop looks like synchronization problems with bindings responding to other events than their own. If I run from a terminal things seem to work out. Is it standard development practice to run code from a terminals ($ python program.py)? What's the 'program.pyc' for if the source is compiled every time? I use Python 2.6 on Ubuntu 10.04 LTS. Thankful for any suggestion Frederic -- http://mail.python.org/mailman/listinfo/python-list
How to read image data into Tkinter Canvas?
Hi, Familiarizing myself with Tkinter I'm stuck trying to fill a Canvas with an image. I believe the class I need is PhotoImage rather than BitmapImage. But I have no luck with either. The PhotoImage doc lists available handlers for writing GIF and PPM files. It doesn't say anything about reading. I would assume that any widely used image format would activate the appropriate handler automatically. To work with formats other than GIF and PPM the doc recommends to resort to the Image module (PIL). This approach also failed. I did manage to read a GIF file into PhotoImage, which seems to let my code off the hook. And I have made sure beyond any doubt that my image files exist and open with PIL. I must be doing something wrong and will much appreciate any help. Frederic - Here's what happens: First trial with PhotoImage: . . . canvas = Canvas (root) picture = PhotoImage (file = /home/fr/temp/wandbild.bmp) image = canvas.create_image (10, 10, anchor = NW, image = picture) . . . Traceback (most recent call last): File tk2.py, line 23, in module picture = PhotoImage (file = /home/fr/temp/wandbild.bmp) File /usr/lib/python2.6/lib-tk/Tkinter.py, line 3288, in __init__ Image.__init__(self, 'photo', name, cnf, master, **kw) File /usr/lib/python2.6/lib-tk/Tkinter.py, line 3244, in __init__ self.tk.call(('image', 'create', imgtype, name,) + options) _tkinter.TclError: couldn't recognize data in image file /home/fr/temp/wandbild.bmp - Second trial with BitmapImage: . . . picture = BitmapImage (file = /home/fr/temp/wandbild.bmp) . . . Traceback (most recent call last): File tk2.py, line 22, in module picture = BitmapImage (file = /home/fr/temp/wandbild.bmp) File /usr/lib/python2.6/lib-tk/Tkinter.py, line 3347, in __init__ Image.__init__(self, 'bitmap', name, cnf, master, **kw) File /usr/lib/python2.6/lib-tk/Tkinter.py, line 3244, in __init__ self.tk.call(('image', 'create', imgtype, name,) + options) _tkinter.TclError: format error in bitmap data - Third trial with Image.open: . . . picture = Image.open (/home/fr/temp/wandbild.bmp) print picture image = canvas.create_image (10, 10, anchor = NW, image = picture) . . . JpegImagePlugin.JpegImageFile image mode=RGB size=963x616 at 0x9A4D84C Traceback (most recent call last): File tk2.py, line 24, in module image = canvas.create_image (10, 10, anchor = NW, image = picture) File /usr/lib/python2.6/lib-tk/Tkinter.py, line 2159, in create_image return self._create('image', args, kw) File /usr/lib/python2.6/lib-tk/Tkinter.py, line 2150, in _create *(args + self._options(cnf, kw _tkinter.TclError: image BmpImagePlugin.BmpImageFile image mode=RGB size=3933x2355 at 0x9A0D84C doesn't exist - Same thing happens with JPG files. As I said, GIF works into PhotoImage, but that's the only format I managed. -- http://mail.python.org/mailman/listinfo/python-list
try - except. How to identify errors unknown in advance?
Hi all, I'd like to log MySQL errors. If I do: try: (command) except MySQLdb.OperationalError, e: print e I may get something like: (1136, Column count doesn't match value count at row 1) If I don't know in advance which error to expect, but on the contrary want to find out which error occurred, I can catch any error by omitting the name: except: (handle) But now I don't have access to the error message 'e'. I'm sure there's a way and it's probably ridiculously simple. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: try - except. How to identify errors unknown in advance?
On Wed, 2011-11-16 at 09:09 -0800, Chris Kaynor wrote: On Wed, Nov 16, 2011 at 8:57 AM, Frederic Rentsch anthra.nor...@bluewin.ch wrote: Hi all, I'd like to log MySQL errors. If I do: try: (command) except MySQLdb.OperationalError, e: print e I may get something like: (1136, Column count doesn't match value count at row 1) If I don't know in advance which error to expect, but on the contrary want to find out which error occurred, I can catch any error by omitting the name: except: (handle) But now I don't have access to the error message 'e'. I'm sure there's a way and it's probably ridiculously simple. except Exception, e: (or, in Py3, except Exception as e is prefereed). Note that you should generally avoid bare except statements except: as that will catch everything, including KeyboardInterrupt and SystemExit which may not be desirable. Even without saving the exception in the except statement, you can get the type, value, and traceback with the sys.exc_info command. See http://docs.python.org/library/sys.html#sys.exc_info For example: pyimport sys pytry: py raise RuntimeError py except: py print sys.exc_info() py (type 'exceptions.RuntimeError', RuntimeError(), traceback object at 0x02371588) Chris, Thanks very much! Great help! Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: String multi-replace
On Wed, 2010-11-17 at 21:12 -0800, Sorin Schwimmer wrote: Thanks for your answers. Benjamin Kaplan: of course dict is a type... silly me! I'll blame it on the time (it's midnight here). Chris Rebert: I'll have a look. Thank you both, SxN Forgive me if this is off the track. I haven't followed the thread. I do have a little module that I believe does what you attempted to do: multiple substitutions using a regular expression that joins a bunch of targets with '|' in between. Whether or not you risk unintended translations as Dave Angel pointed out where the two characters or one of your targets join coincidentally you will have to determine. If so you can't use this approach. If, on the other hand, your format is safe it'll work just fine. Use like this: import translator t = translator.Translator (nodia.items ()) t (name) # Your example 'Rasca' Frederic class Translator: Will translate any number of targets, handling them correctly if some overlap. Making Translator T = Translator (definitions, [eat = 1]) 'definitions' is a sequence of pairs: ((target, substitute),(t2, s2), ...) 'eat = True' will make an extraction filter that lets only the replaced targets pass. Definitions example: (('a','A'),('b','B'),('ab','ab'),('abc','xyz'), ('\x0c', 'page break'), ('\r\n','\n'), (' ','\t')) # ('ab','ab') see Tricks. Order doesn't matter. Testing T.test (). Translates the definitions and prints the result. All targets must look like the substitutes as defined. If a substitute differs, it has been affected by the translation. (E.g. 'A'|'A' ... 'page break'|'pAge BreAk'). If this is not intended---the effect can be useful---protect the affected substitute by translating it to itself. See Tricks. Running translation = T (source) Tricks Deletion: ('target', '') Exception: (('\n',''), ('\n\n','\n\n')) # Eat LF except paragraph breaks. Exception: (('\n', '\r\n'), ('\r\n',\r\n')) # Unix to DOS, would leave DOS unchanged Translation cascade: # Unwrap paragraphs, Unix or DOS, restoring inter-word space if missing, Mark_LF = Translator ((('\n','+LF+'),('\r\n','+LF+'),('\n\n','\n\n'),('\r\n\r\n','\r\n\r\n'))) # Pick positively identifiable mark for end of lines in either Unix or MS-DOS. Single_Space_Mark = Translator (((' +LF+', ' '),('+LF+', ' '),('-+LF+', ''))) no_lf_text = Single_Space_Mark (Mark_LF (text)) Translation cascade: reptiles = T_latin_english (T_german_latin (reptilien)) Limitations 1. The number of substitutions and the maximum size of input depends on the respective capabilities of the Python re module. 2. Regular expressions will not work as such but will be handled literally. Author: Frederic Rentsch (i...@anthra-norell.ch). def __init__ (self, definitions, eat = 0): ''' definitions: a sequence of pairs of strings. ((target, substitute), (t, s), ...) eat: False (0) means translate: unaffected data passes unaltered. True (1) means extract: unaffected data doesn't pass (gets eaten). Extraction filters typically require substitutes to end with some separator, else they fuse together. (E.g. ' ', '\t' or '\n') 'eat' is an attribute that can be switched anytime. ''' self.eat = eat self.compile_sequence_of_pairs (definitions) def compile_sequence_of_pairs (self, definitions): ''' Argument 'definitions' is a sequence of pairs: (('target 1', 'substitute 1'), ('t2', 's2'), ...) Order doesn't matter. ''' import re self.definitions = definitions targets, substitutes = zip (*definitions) re_targets = [re.escape (item) for item in targets] re_targets.sort (reverse = True) self.targets_set = set (targets) self.table = dict (definitions) regex_string = '|'.join (re_targets) self.regex = re.compile (regex_string, re.DOTALL) def __call__ (self, s): hits = self.regex.findall (s) nohits = self.regex.split (s) valid_hits = set (hits) self.targets_set # Ignore targets with illegal re modifiers. if valid_hits: substitutes = [self.table [item] for item in hits if item in valid_hits] + [] # Make lengths equal for zip to work right if self.eat: return ''.join (substitutes) else: zipped = zip (nohits, substitutes) return ''.join (list (reduce (lambda a, b: a + b, [zipped][0]))) + nohits [-1] else: if self.eat: return '' else: return s def test (self): ''' Translates the definitions and prints the result. All targets must look like the substitutes as defined. If a substitute differs, it has been affected by the translation, indicating a potential problem, should the substitute occur in the source. ''' targets_translated = [self (item [0]) for item in self.definitions] substitutes = [self (item [1
Re: Financial time series data
On Fri, 2010-09-03 at 19:58 +0200, Virgil Stokes wrote: import urllib2 import re def get_SP500_symbolsX (): symbols = [] lsttradestr = re.compile('Last Trade:') k = 0 for page in range(10): url = 'http://finance.yahoo.com/q/cp?s=%5EGSPCc='+str(page) print url f = urllib2.urlopen (url) html = f.readlines () f.close () for line in html: if line.lstrip ().startswith ('/scriptspan id=yfs_params_vcr'): line_split = line.split (':') s = [item.strip ().upper () for item in line_split [5].replace ('','').split (',')] for symb in s: url = http://finance.yahoo.com/q?s=+symb f = urllib2.urlopen(url) html = f.readlines() f.close() for line in html: if lsttradestr.search(line): k += 1 print 'k = %3d (%s)' %(k,symb) # Here is where I will extract the numerical values and place # # them in an approrpriate file symbols.extend (s [:-3]) return symbols # Not quite 500 -- which is correct (for example p. 2 has only 49 symbols!) # Actually the SP 500 as shown does not contain 500 stocks (symbols) symbols = get_SP500_symbolsX() pass And thanks for your help Frederic --- Have a good day! :-) --V Good going! You get the idea. Here's my try for a cleaned-up version that makes the best use of the facility and takes only fifteen seconds to complete (on my machine). You may want to look at historical quotes too. Trent Nelson seems to have a ready-made solution for this. --- import urllib2 import re def get_current_SP500_quotes_from_Yahoo (): symbol_reader = re.compile ('([a-z-.]+,)+[a-z-.]+') # Make sure you include all characters that may show up in symbols, csv_data = '' for page in range (10): url = 'http://finance.yahoo.com/q/cp?s=%5EGSPCc=' + str (page) print url f = urllib2.urlopen (url) html = f.readlines () f.close () for line in html: if line.lstrip ().startswith ('/scriptspan id=yfs_params_vcr'): symbols = symbol_reader.search (line).group () ## symbols = line.split (':')[5][2:-18] ## ^ This is an alternative to the regex. It won't stumble over ## unexpected characters in symbols, but depends on the line ## line format to stay put. # print symbols.count (',') + 1 # Uncomment to check for = 50 url = 'http://download.finance.yahoo.com/d/quotes.csv?s=% sf=sl1d1t1c1ohgve=.csv' % symbols # Regex happens to grab symbols correctly formatted # print url f = urllib2.urlopen (url) csv_data += f.read () f.close () break return csv_data --- Here is what you get: A,29.85,9/3/2010,4:01pm,+0.64,29.49,29.99,29.49,2263815 AA,10.88,9/3/2010,4:00pm,+0.05,11.01,11.07,10.82,16634520 AEE,28.65,9/3/2010,4:01pm,+0.19,28.79,28.79,28.46,3029885 ... 494 lines in all (today) Symbol, Current or close, Date, Time, Change, Open, High, Low, Volume --- Good luck to you in the footsteps of Warren Buffet! Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Financial time series data
On Fri, 2010-09-03 at 13:29 +0200, Virgil Stokes wrote: A more direct question on accessing stock information from Yahoo. First, use your browser to go to: http://finance.yahoo.com/q/cp?s=% 5EGSPC+Components Now, you see the first 50 rows of a 500 row table of information on SP 500 index. You can LM click on 1 -50 of 500 |First|Previous|Next|Last below the table to position to any of the 10 pages. I would like to use Python to do the following. Loop on each of the 10 pages and for each page extract information for each row --- How can this be accomplished automatically in Python? Let's take the first page (as shown by default). It is easy to see the link to the data for A is http://finance.yahoo.com/q?s=A. That is, I can just move my cursor over the A and I see this URL in the message at the bottom of my browser (Explorer 8). If I LM click on A then I will go to this link --- Do this! You should now see a table which shows information on this stock and this is the information that I would like to extract. I would like to do this for all 500 stocks without the need to enter the symbols for them (e.g. A, AA, etc.). It seems clear that this should be possible since all the symbols are in the first column of each of the 50 tables --- but it is not at all clear how to extract these automatically in Python. Hopefully, you understand my problem. Again, I would like Python to cycle through these 10 pages and extract this information for each symbol in this table. --V Here's a quick hack to get the SP500 symbols from the visual page with the index letters. From this collection you can then order fifty at a time from the download facility. (If you get a better idea from Yahoo, you'll post it of course.) def get_SP500_symbols (): import urllib symbols = [] url = 'http://finance.yahoo.com/q/cp?s=^GSPCalpha=%c' for c in [chr(n) for n in range (ord ('A'), ord ('Z') + 1)]: print url % c f = urllib.urlopen (url % c) html = f.readlines () f.close () for line in html: if line.lstrip ().startswith ('/scriptspan id=yfs_params_vcr'): line_split = line.split (':') s = [item.strip ().upper () for item in line_split [5].replace ('', '').split (',')] symbols.extend (s [:-3]) return symbols # Not quite 500 (!?) Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Financial time series data
On Fri, 2010-09-03 at 16:48 +0200, Virgil Stokes wrote: On 03-Sep-2010 15:45, Frederic Rentsch wrote: On Fri, 2010-09-03 at 13:29 +0200, Virgil Stokes wrote: A more direct question on accessing stock information from Yahoo. First, use your browser to go to: http://finance.yahoo.com/q/cp?s=% 5EGSPC+Components Now, you see the first 50 rows of a 500 row table of information on SP 500 index. You can LM click on 1 -50 of 500 |First|Previous|Next|Last below the table to position to any of the 10 pages. I would like to use Python to do the following. Loop on each of the 10 pages and for each page extract information for each row --- How can this be accomplished automatically in Python? Let's take the first page (as shown by default). It is easy to see the link to the data for A is http://finance.yahoo.com/q?s=A. That is, I can just move my cursor over the A and I see this URL in the message at the bottom of my browser (Explorer 8). If I LM click on A then I will go to this link --- Do this! You should now see a table which shows information on this stock and this is the information that I would like to extract. I would like to do this for all 500 stocks without the need to enter the symbols for them (e.g. A, AA, etc.). It seems clear that this should be possible since all the symbols are in the first column of each of the 50 tables --- but it is not at all clear how to extract these automatically in Python. Hopefully, you understand my problem. Again, I would like Python to cycle through these 10 pages and extract this information for each symbol in this table. --V Here's a quick hack to get the SP500 symbols from the visual page with the index letters. From this collection you can then order fifty at a time from the download facility. (If you get a better idea from Yahoo, you'll post it of course.) def get_SP500_symbols (): import urllib symbols = [] url = 'http://finance.yahoo.com/q/cp?s=^GSPCalpha=%c' for c in [chr(n) for n in range (ord ('A'), ord ('Z') + 1)]: print url % c f = urllib.urlopen (url % c) html = f.readlines () f.close () for line in html: if line.lstrip ().startswith ('/scriptspan id=yfs_params_vcr'): line_split = line.split (':') s = [item.strip ().upper () for item in line_split [5].replace ('', '').split (',')] symbols.extend (s [:-3]) return symbols # Not quite 500 (!?) Frederic I made a few modifications --- very minor. But, I believe that it is a little faster. import urllib2 def get_SP500_symbolsX (): symbols = [] for page in range(0,9): url = 'http://finance.yahoo.com/q/cp?s=%5EGSPCc='+str(page) print url f = urllib2.urlopen (url) html = f.readlines () f.close () for line in html: if line.lstrip ().startswith ('/scriptspan id=yfs_params_vcr'): line_split = line.split (':') s = [item.strip ().upper () for item in line_split [5].replace ('','').split (',')] symbols.extend (s [:-3]) return symbols # Not quite 500 -- which is correct (for example p. 2 has only 49 symbols!) # Actually the SP 500 as shown does not contain 500 stocks (symbols) symbols = get_SP500_symbolsX() pass Oh, yes, and there's no use reading lines to the end once the symbols are in the bag. The symbol-line-finder conditional section should end with break. And do let us know if you get an answer from Yahoo. Hacks like this are unreliable. They fail almost certainly the next time a page gets redesigned, which can be any time. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: expression in an if statement
On Thu, 2010-08-19 at 00:12 +0200, Thomas Jollans wrote: On Wednesday 18 August 2010, it occurred to John Nagle to exclaim: On 8/18/2010 11:24 AM, ernest wrote: Hi, In this code: if set(a).union(b) == set(a): pass Does Python compute set(a) twice? CPython does. Shed Skin might optimize. Don't know about Iron Python. I doubt any actual Python implementation optimizes this -- how could it? And why should it if a programmer uses its facilities inefficiently. I would write if set(a).issuperset (b): pass Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Simple Problem but tough for me if i want it in linear time
On Mon, 2010-08-16 at 23:17 +, Steven D'Aprano wrote: On Mon, 16 Aug 2010 20:40:52 +0200, Frederic Rentsch wrote: How about [obj for obj in dataList if obj.number == 100] That should create a list of all objects whose .number is 100. No need to cycle through a loop. What do you think the list comprehension does, if not cycle through a loop? -- Steven What I think is that list comprehensions cycle through a loop a lot faster than a coded loop (for n in ...:). As at the time of my post only coded loops had been proposed and the OP was concerned about speed, I thought I'd propose a list comprehension. I guess my explanation was poorly phrased. Thanks for the reminder. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Simple Problem but tough for me if i want it in linear time
On Sun, 2010-08-15 at 15:14 +0200, Peter Otten wrote: ChrisChia wrote: dataList = [a, b, c, ...] where a, b, c are objects of a Class X. In Class X, it contains self.name and self.number If i wish to test whether a number (let's say 100) appears in one of the object, and return that object, is that only fast way of solving this problem without iterating through every object to see the number value? dataList.__contains__ can only check my object instance name... anyone can solve this in linear complexity? Well, iteration as in next(item for item in dataList if item.number == 100) is O(n) and list.__contains__() has no magic way to do better. If you need O(1) lookup you can use a dict or collections.defaultdict that maps item.number to a list (or set) of X instances: lookup = {} for item in dataList: lookup.setdefault(item.number, []).append(item) print lookup[100] Peter How about [obj for obj in dataList if obj.number == 100] That should create a list of all objects whose .number is 100. No need to cycle through a loop. If .number doesn't repeat get your object at index 0. The approach may seem inefficient for the purpose of extracting a single item, but the list needs to be gone through in any case and the list comprehension is surely the most efficient way to do it. Frederic -- http://mail.python.org/mailman/listinfo/python-list
'reload M' doesn't update 'from M inport *'
I develop in an IDLE window. Module M says 'from service import *'. Next I correct a mistake in function 'service.f'. Now 'service.f' works fine. I do 'reload (service); reload (M)'. The function 'M.f' still misbehaves. 'print inspect.getsource (service.f)' and 'print inspect.getsource (M.f)' shows the same corrected code. 'print service.f' and 'print M.f' show different ids. So I do 'del M; reload (M)'. Nothing changes. I delete M again and run gc.collect () to really clean house. I reload M again and still nothing changes. The id of the reloaded function 'M.f' is still the same as it was before the purge and so M.f still isn't fixed. I know I have more radical options, such as starting a new IDLE window. That would save me time, but I'd like to take the opportunity to understand what is happening. Surely someone out there knows. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: 'reload M' doesn't update 'from M inport *'
On Fri, 2010-07-09 at 15:58 +, Steven D'Aprano wrote: On Fri, 09 Jul 2010 15:02:25 +0200, Frederic Rentsch wrote: I develop in an IDLE window. Module M says 'from service import *'. Next I correct a mistake in function 'service.f'. Now 'service.f' works fine. from service import * should be considered advanced functionality that is discouraged unless you really know what you are doing, precisely for the problems you are experiencing. You should try to avoid it. But putting that aside, if you have done from service import * in module m, where are you getting service.f from? The only way that is possible is if you ALSO say import service. I do 'reload (service); reload (M)'. The function 'M.f' still misbehaves. 'print inspect.getsource (service.f)' and 'print inspect.getsource (M.f)' shows the same corrected code. inspect.getsource always looks at the source code on disk, no matter what the byte code in memory actually says. 'print service.f' and 'print M.f' show different ids. So I do 'del M; reload (M)'. Nothing changes. I delete M again and run gc.collect () to really clean house. I reload M again and still nothing changes. The id of the reloaded function 'M.f' is still the same as it was before the purge and so M.f still isn't fixed. I know I have more radical options, such as starting a new IDLE window. That would save me time, but I'd like to take the opportunity to understand what is happening. Surely someone out there knows. Yes. You have to understand importing. Let's start with the simple: import m In *very* simplified pseudo-code, this does: look for module m in the global cache if not there, then: search for m.py compile it to a Module object put the Module object in the cache create a new name m in the local namespace set the name m to the Module object in the cache Now let's compare it to: from m import f look for module m in the global cache if not there, then: search for m.py compile it to a Module object put the Module object in the cache look for object named f in the Module object create a new name f in the local namespace set the name f to cached object The important thing to notice is the the name f is a local variable. It doesn't, and can't, remember that it comes from module m. Reloading m can't do anything to f, because the connection is lost. Now consider that the object f that came from m was itself imported from another module, service. Reloading service doesn't help, because m.f doesn't know it came from service. Reloading m doesn't help, because all that does is run from service import f again, and that just fetches f from the global cache. The simplest, easiest way of dealing with this is not to have to deal with it: don't use from service import f, and ESPECIALLY don't use from service import *. Always use fully-qualified importing: import service service.f Now reload(service) should do what you expect. The other way is not to bother with reload. It's not very powerful, only good for the simplest use in the interactive interpreter. Just exit the interpreter and restart it. -- Steven Thank you very much for your excellent explanation! I must say that I haven't been using the from soandso import ... formula at all. I thought it might expose names to collision, and why should I assume the responsibility if I can avoid the problem altogether using explicit names. If I used the, shall we say, direct import this time it was in an effort to develop a more extensive program. I thought if a module grows beyond a size that's comfortable to edit, I could just move select segments to separate files and replace the vacancy with from the_respective_segment_module import *, analogous to #include in C. The remedy seems to have side-effects that can kill the patient. So I'll go back to the explicit imports, then. No problem at all. Thanking you and the other helpers too Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: 'reload M' doesn't update 'from M inport *'
On Fri, 2010-07-09 at 19:38 +0200, Jean-Michel Pichavant wrote: Frederic Rentsch wrote: I develop in an IDLE window. Module M says 'from service import *'. Next I correct a mistake in function 'service.f'. Now 'service.f' works fine. I do 'reload (service); reload (M)'. The function 'M.f' still misbehaves. 'print inspect.getsource (service.f)' and 'print inspect.getsource (M.f)' shows the same corrected code. 'print service.f' and 'print M.f' show different ids. So I do 'del M; reload (M)'. Nothing changes. I delete M again and run gc.collect () to really clean house. I reload M again and still nothing changes. The id of the reloaded function 'M.f' is still the same as it was before the purge and so M.f still isn't fixed. I know I have more radical options, such as starting a new IDLE window. That would save me time, but I'd like to take the opportunity to understand what is happening. Surely someone out there knows. Frederic Hi, Don't use reload, this is nothing but a trap, espacially if your using it to update your objects with the code you are writting. JM I've found reload very usable for development in IDLE. IDLE memorizes my input, and the variables I assign output to. If restart IDLE I lose it all and start over. That is an awfully awkward alternative to reload, an alternative I wouldn't consider. I found reload tricky with several modules, because all dependencies need to be updated and which way they go isn't always obvious. Reloading all modules in the right order works for me. The reload commands come up with Alt-P as long, precisely, as I don't restart IDLE. S : You're misusing the del statement. It does not remove any object from mmory, however, it removes the reference to it, the object is still in memory. They are very few cases where del is usefull in python, so try to avoid using it as well. I understand that things going out of scope delete themselves. I have used del on occasion, for instance, to get rid of invalid members of a list or a dictionary. It has to be done in two passes, though, because neither can be altered during an iteration. The first pass makes a delete list of indices or keys, so that the actual deletion iterates through the delete list, not the object deleted from. Would you call that a misuse? Frederic -- http://mail.python.org/mailman/listinfo/python-list
Requesting direction for installation problem
Hi, Where can one get assistance if a Windows installation service fails to install an msi installer? I used to download zip files, but they seem to have been replaced with msi files. I know this issue is off topic here. So my question simply is: where is it not off topic? Thanks for any hint Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: problem deriving form type long
Gabriel Genellina wrote: En Mon, 21 Jan 2008 18:33:10 -0200, Frederic Rentsch [EMAIL PROTECTED] escribió: Hi, here's something that puzzles me: class Fix_Point (long): def __init__ (self, l): long.__init__ (self, l * 0x1): fp = Fix_Point (99) fp 99 You have to override __new__, not __init__. Immutable types like numbers and tuples don't use __init__. See http://docs.python.org/ref/customization.html That's a big help! Thank you very much. Frederic -- http://mail.python.org/mailman/listinfo/python-list
problem deriving form type long
Hi, here's something that puzzles me: class Fix_Point (long): def __init__ (self, l): long.__init__ (self, l * 0x1): fp = Fix_Point (99) fp 99 With prints: class Fix_Point (long): def __init__ (self, l): print l l_ = l * 2 print l_ long.__init__ (self, l_) print self fp = Fix_Point (99) 99 198 99 I have tried dozens of variations: type casts, variables, ... nothing doing. Fix_Point instances always get the argument assigned regardless of the transformation __init__ () performs on it prior to calling long.__init__ (). Looks like long.__init__ () isn't called at all. Any idea anyone what's going on? Frederic (P.S. I am not currently a subscriber. I was and had to bail out when I couldn't handle the volume anymore. To subscribe just to post one question doesn't seem practical at all. So, I don't even know if this message goes through. In case it does, I would appreciate a CC directly to my address, as I don't think I can receive the list. Thanks a million.) -- http://mail.python.org/mailman/listinfo/python-list
Re: Parsing HTML
mtuller wrote: Alright. I have tried everything I can find, but am not getting anywhere. I have a web page that has data like this: tr td headers=col1_1 style=width:21% span class=hpPageText LETTER/span/td td headers=col2_1 style=width:13%; text-align:right span class=hpPageText 33,699/span/td td headers=col3_1 style=width:13%; text-align:right span class=hpPageText 1.0/span/td td headers=col4_1 style=width:13%; text-align:right /tr What is show is only a small section. I want to extract the 33,699 (which is dynamic) and set the value to a variable so that I can insert it into a database. I have tried parsing the html with pyparsing, and the examples will get it to print all instances with span, of which there are a hundred or so when I use: for srvrtokens in printCount.searchString(printerListHTML): print srvrtokens If I set the last line to srvtokens[3] I get the values, but I don't know grab a single line and then set that as a variable. I have also tried Beautiful Soup, but had trouble understanding the documentation, and HTMLParser doesn't seem to do what I want. Can someone point me to a tutorial or give me some pointers on how to parse html where there are multiple lines with the same tags and then be able to go to a certain line and grab a value and set a variable's value to that? Thanks, Mike Posted problems rarely provide exhaustive information. It's just not possible. I have been taking shots in the dark of late suggesting a stream-editing approach to extracting data from htm files. The mainstream approach is to use a parser (beautiful soup or pyparsing). Often times nothing more is attempted than the location and extraction of some text irrespective of page layout. This can sometimes be done with a simple regular expression, or with a stream editor if a regular expression gets too unwieldy. The advantage of the stream editor over a parser is that it doesn't mobilize an arsenal of unneeded functionality and therefore tends to be easier, faster and shorter to implement. The editor's inability to understand structure isn't a shortcoming when structure doesn't matter and can even be an advantage in the presence of malformed input that sends a parser on a tough and potentially hazardous mission for no purpose at all. SE doesn't impose the study of massive documentation, nor the memorization of dozens of classes, methods and what not. The following four lines would solve the OP's problem (provided the post really is all there is to the problem): import re, SE# http://cheeseshop.python.org/pypi/SE/2.3 Filter = SE.SE ('EAT ~(?i)col[0-9]_[0-9](.|\n)*?/td~==SOME SPLIT MARK') r = re.compile ('(?i)(col[0-9]_[0-9])(.|\n)*?([0-9,]+)/span') for line in Filter (s).split ('SOME SPLIT MARK'): print r.search (line).group (1, 3) ('col2_1', '33,699') ('col3_1', '0') ('col4_1', '7,428') --- Input: s = ''' td headers=col1_1 style=width:21% span class=hpPageText LETTER/span/td td headers=col2_1 style=width:13%; text-align:right span class=hpPageText 33,699/span/td td headers=col3_1 style=width:13%; text-align:right span class=hpPageText 1.0/span/td td headers=col5_1 style=width:13%; text-align:right span class=hppagetext 7,428/span/td /tr''' The SE object handles file input too: for line in Filter ('file_name', '').split ('SOME SPLIT MARK'): # '' commands string output print r.search (line).group (1, 3) -- http://mail.python.org/mailman/listinfo/python-list
Re: Find and replace in a file with regular expression
TOXiC wrote: Hi everyone, First I say that I serched and tryed everything but I cannot figure out how I can do it. I want to open a a file (not necessary a txt) and find and replace a string. I can do it with: import fileinput, string, sys fileQuery = Text.txt sourceText = '''SOURCE''' replaceText = '''REPLACE''' def replace(fileName, sourceText, replaceText): file = open(fileName, r) text = file.read() #Reads the file and assigns the value to a variable file.close() #Closes the file (read session) file = open(fileName, w) file.write(text.replace(sourceText, replaceText)) file.close() #Closes the file (write session) print All went well, the modifications are done replacemachine(fileQuery, sourceText, replaceText) Now all went ok but I'm wondering if it's possible to replace text if / sourceText/ match a regex. Help me please! Thx in advance Try this: import SE # from http://cheeseshop.python.org/pypi/SE/2.3 replacements = 'SOURCE=REPLACE another source=another replace ~[0-9]+~=int ~[0-9]+\\.[0-9]+~=float ~' # Define as many replacements as you like. Identify regexes placing them between '~' Stream_Editor = SE.SE (replacements) Stream_Editor (input_file, output_file) That's it. PS 1: Your Stream_Editor accepts strings as well as file names and then returns a string by default. This is a great help for developing substitution sets interactively. print Stream_Editor (''' If it works, this SOURCE should read REPLACE and another source should become another replace and this 123456789 should become int and this 12345.6789 is a float and so should read float.''') If it works, this REPLACE should read REPLACE and another replace should become another replace and this int should become int and this float is a float and so should read float. PS 2: It is convenient to keep large and frequently used substitution sets in text files. The SE constructor accepts a file name instead of the replacements string: Stream_Edtor = SE.SE ('path/replacement_definitions_file') Regards Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Type casting a base class to a derived one?
Chris Mellon wrote: On 11 Jan 2007 15:01:48 +0100, Neil Cerutti [EMAIL PROTECTED] wrote: On 2007-01-11, Frederic Rentsch [EMAIL PROTECTED] wrote: If I derive a class from another one because I need a few extra features, is there a way to promote the base class to the derived one without having to make copies of all attributes? class Derived (Base): def __init__ (self, base_object): # ( copy all attributes ) ... This looks expensive. Moreover __init__ () may not be available if it needs to to something else. Thanks for suggestions How does it make sense to cast a base to a derived in your application? I can't figure out any circumstance when you'd need to do this in Python. Upcasting like this is something you do in statically typed languages. I suspect that the OP doesn't really believe dynamic casting works and doesn't want to pass a derived class for some reason. What for? If an instance needs to collect a substantial amount of data and needs to perform a substantial amount of processing in order to analyze that data, and if the appropriate type of the instance depends on the analysis, I thought that the instance might at that point just kind of slip into the appropriate identity. After studying the various helpful suggestions, some of which, like this one, question the wisdom of such an approach, I think I see the light: I'd have a class that does the collecting and the analyzing, or even two classes: one collecting the other analyzing and then, depending on the outcome of the analysis, make the appropriate processor and hand it the data it needs. Right? Thank you all very much for your input. Frederic (OP) -- http://mail.python.org/mailman/listinfo/python-list
Type casting a base class to a derived one?
Hi all, If I derive a class from another one because I need a few extra features, is there a way to promote the base class to the derived one without having to make copies of all attributes? class Derived (Base): def __init__ (self, base_object): # ( copy all attributes ) ... This looks expensive. Moreover __init__ () may not be available if it needs to to something else. Thanks for suggestions Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: textwrap.dedent replaces tabs?
Tom Plunket wrote: Frederic Rentsch wrote: Your rules seem incomplete. Not my rules, the stated documentation for dedent. My understanding of them may not be equivalent to yours, however. It's not about understanding, It's about the objective. Let us consider the difference between passing a driving test and riding a bicycle in city traffic. The objective of passing the test is getting the license and the means is knowing the rules. The objective of riding the bicycle is surviving and the means is anticipating all possible breaches of rules on he part of motorists. What if common tabs remain after stripping common white space? What if we just go with, [r]emove any whitespace than can be uniformly removed from the left of every line in `text`. ? Does this never happen? Or can we hope it doesn't happen? Hope has no place in programming software that is to be used by others. That's exactly what I am saying. That's exactly why it may be a good idea to provide preventive measures for rules being breached be those others over whom we have no control. To err on the side of caution I complete your rules and this is my (tested) attempt at expressing them pythonically. Inasmuch as my rules have been expressed via tests, the provided code fails four of the five tests provided. toms_test_data = ( ( \n Hello\n World, # Do this \nHello\n World, ), # Expect this ( \n\tHello\n\t World, \nHello\n World, ), ( \t\tHello\n\tWorld, \tHello\nWorld, ), ( Hello\n\tWorld, Hello\n\tWorld, ), ( \t Hello\n \tWorld, \t Hello\n \tWorld, ), ) for dedent_this, expect_this in toms_test_data: done = '\n'.join (dedent (dedent_this.splitlines ())) if done == expect_this: print 'BRAVO!!!' else: print 'SHAME ON YOU!!!' BRAVO!!! BRAVO!!! BRAVO!!! BRAVO!!! BRAVO!!! You seem to have plugged my function into your tester. I wasn't concerned about your testing interface but about the dedentation. (I admit it does look awfully sevety-ish. Just a vulgar little function.) Seventys-ish is as much a statement about the lack of statement about how you actually tested it as it is that an implementation was made apparently without understanding of the requirements. -tom! Best regards Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: textwrap.dedent replaces tabs?
Tom Plunket wrote: Frederic Rentsch wrote: It this works, good for you. I can't say I understand your objective. (You dedent common leading tabs, except if preceded by common leading spaces (?)). I dedent common leading whitespace, and tabs aren't equivalent to spaces. E.g. if some text is indented exclusively with tabs, then the leading tabs are stripped appropriately. If some other text is indented with common leading spaces, those are stripped appropriately. If the text to be stripped has some lines starting with spaces and others starting with tabs, there are no /common/ leading whitespace characters, and thus nothing is stripped. Your rules seem incomplete. What if common tabs remain after stripping common white space? Does this never happen? Or can we hope it doesn't happen? To err on the side of caution I complete your rules and this is my (tested) attempt at expressing them pythonically. (I admit it does look awfully sevety-ish. Just a vulgar little function.) Cheers Frederic - def dedent (lines): leading_space_re = re.compile (' *') leading_tab_re = re.compile ('\t*') number_of_lines = len (lines) while 1: common_space_length = common_tab_length = 10 for line in lines: if line: # No '\n' try: common_space_length = min (common_space_length, len (leading_space_re.match (line).group ())) except AttributeError: pass try: common_tab_length = min (common_tab_length, len (leading_tab_re.match (line).group ())) except AttributeError: pass if 0 common_space_length 10: for i in xrange (number_of_lines): lines [i] = lines [i][common_space_length:] elif 0 common_tab_length 10: for i in xrange (number_of_lines): lines [i] = lines [i][common_tab_length:] else: break return lines -- http://mail.python.org/mailman/listinfo/python-list
Re: BeautifulSoup vs. loose chars
John Nagle wrote: Felipe Almeida Lessa wrote: On 26 Dec 2006 04:22:38 -0800, placid [EMAIL PROTECTED] wrote: So do you want to remove or replace them with amp; ? If you want to replace it try the following; I think he wants to replace them, but just the invalid ones. I.e., This this amp; that would become This amp; this amp; that No, i don't know how to do this efficiently. =/... I think some kind of regex could do it. Yes, and the appropriate one is: krefindamp = re.compile(r'(?!(\w|#)+;)') ... xmlsection = re.sub(krefindamp,'amp;',xmlsection) This will replace an '' with 'amp' if the '' isn't immediately followed by some combination of letters, numbers, and '#' ending with a ';' Admittedly this would let something like 'xx#2;', which isn't a legal entity, through unmodified. There's still a potential problem with unknown entities in the output XML, but at least they're recognized as entities. John Nagle Here's another idea: s = '''html htm tag should not translate should be amp; xx#2; isn't a legal entity and should translate #123; is a legal entity and should not translate /html import SE # http://cheeseshop.python.org/pypi/SE/2.3 HTM_Escapes = SE.SE (definitions) # See definitions below the dotted line print HTM_Escapes (s) html htm tag should not translate gt; amp; should be amp; gt; amp;xx#2; isnquot;t a legal entity and should translate gt; #123; is a legal entity and should not translate /html Regards Frederic -- definitions = ''' # Do # Don't do # =nbsp; nbsp;== # 32 20 (34)=dquot; dquot;== # 34 22 =amp; amp;== # 38 26 '=quot; quot;== # 39 27 =lt; lt;==# 60 3c =gt; gt;==# 62 3e ©=copy; copy;== # 169 a9 ·=middot; middot;==# 183 b7 »=raquo;raquo;== # 187 bb À=Agrave; Agrave;==# 192 c0 Á=Aacute; Aacute;==# 193 c1 Â=Acirc;Acirc;== # 194 c2 Ã=Atilde; Atilde;==# 195 c3 Ä=Auml; Auml;== # 196 c4 Å=Aring;Aring;== # 197 c5 Æ=AElig;AElig;== # 198 c6 Ç=Ccedil; Ccedil;==# 199 c7 È=Egrave; Egrave;==# 200 c8 É=Eacute; Eacute;==# 201 c9 Ê=Ecirc;Ecirc;== # 202 ca Ë=Euml; Euml;== # 203 cb Ì=Igrave; Igrave;==# 204 cc Í=Iacute; Iacute;==# 205 cd Î=Icirc;Icirc;== # 206 ce Ï=Iuml; Iuml;== # 207 cf Ð=Eth; Eth;== # 208 d0 Ñ=Ntilde; Ntilde;==# 209 d1 Ò=Ograve; Ograve;==# 210 d2 Ó=Oacute; Oacute;==# 211 d3 Ô=Ocirc;Ocirc;== # 212 d4 Õ=Otilde; Otilde;==# 213 d5 Ö=Ouml; Ouml;== # 214 d6 Ø=Oslash; Oslash;==# 216 d8 Ù=Ugrve;Ugrve;== # 217 d9 Ú=Uacute; Uacute;==# 218 da Û=Ucirc;Ucirc;== # 219 db Ü=Uuml; Uuml;== # 220 dc Ý=Yacute; Yacute;==# 221 dd Þ=Thorn;Thorn;== # 222 de ß=szlig;szlig;== # 223 df à=agrave; agrave;==# 224 e0 á=aacute; aacute;==# 225 e1 â=acirc;acirc;== # 226 e2 ã=atilde; atilde;==# 227 e3 ä=auml; auml;== # 228 e4 å=aring;aring;== # 229 e5 æ=aelig;aelig;== # 230 e6 ç=ccedil; ccedil;==# 231 e7 è=egrave; egrave;==# 232 e8 é=eacute; eacute;==# 233 e9 ê=ecirc;ecirc;== # 234 ea ë=euml; euml;== # 235 eb ì=igrave; igrave;==# 236 ec í=iacute; iacute;==# 237 ed î=icirc;icirc;== # 238 ee ï=iuml; iuml;== # 239 ef ð=eth; eth;== # 240 f0 ñ=ntilde; ntilde;==# 241 f1 ò=ograve; ograve;==# 242 f2 ó=oacute; oacute;==# 243 f3 ô=ocric;ocric;== # 244 f4 õ=otilde; otilde;==# 245 f5 ö=ouml; ouml;== # 246 f6 ø=oslash; oslash;==# 248 f8 ù=ugrave; ugrave;==# 249 f9 ú=uacute; uacute;==# 250 fa û=ucirc;ucirc;== # 251 fb ü=uuml; uuml;== # 252 fc ý=yacute; yacute;==# 253 fd þ=thorn;thorn;== # 254 fe (xff)=#255; # 255 ff #== # All numeric codes ~(.|\n)*?~== # All HTM tags ''' If the ampersand is all you need to handle you can erase the others in the first column. You need to keep the second column though, except the last entry, because the tags don't need protection if '' and '' in the first column are gone. Definitions are easily edited and
Re: textwrap.dedent replaces tabs?
Tom Plunket wrote: Frederic Rentsch wrote: Following a call to dedent () it shouldn't be hard to translate leading groups of so many spaces back to tabs. Sure, but the point is more that I don't think it's valid to change to tabs in the first place. E.g.: input = ' ' + '\t' + 'hello\n' + '\t' + 'world' output = textwrap.dedent(input) will yield all of the leading whitespace stripped, which IMHO is a violation of its stated function. In this case, nothing should be stripped, because the leading whitespace in these two lines does not /actually/ match. Sure, it visually matches, but that's not the point (although I can understand that that's a point of contention in the interpreter anyway, I would have no problem with it not accepting 1 tab = 8 spaces for indentation... But that's another holy war. If I understand your problem, you want to restore the dedented line to its original composition if spaces and tabs are mixed and this doesn't work because the information doesn't survive dedent (). Sure, although would there be a case to be made to simply not strip the tabs in the first place? Like this, keeping current functionality and everything... (although I would think if someone wanted tabs expanded, they'd call expandtabs on the input before calling the function!): def dedent(text, expand_tabs=True): dedent(text : string, expand_tabs : bool) - string Remove any whitespace than can be uniformly removed from the left of every line in `text`, optionally expanding tabs before altering the text. This can be used e.g. to make triple-quoted strings line up with the left edge of screen/whatever, while still presenting it in the source code in indented form. For example: def test(): # end first line with \ to avoid the empty line! s = '''\ hello \t world ''' print repr(s) # prints ' hello\n\t world\n' print repr(dedent(s)) # prints ' hello\n\t world\n' if expand_tabs: text = text.expandtabs() lines = text.split('\n') margin = None for line in lines: if margin is None: content = line.lstrip() if not content: continue indent = len(line) - len(content) margin = line[:indent] elif not line.startswith(margin): if len(line) len(margin): content = line.lstrip() if not content: continue while not line.startswith(margin): margin = margin[:-1] if margin is not None and len(margin) 0: margin = len(margin) for i in range(len(lines)): lines[i] = lines[i][margin:] return '\n'.join(lines) import unittest class DedentTest(unittest.TestCase): def testBasicWithSpaces(self): input = \n Hello\n World expected = \nHello\n World self.failUnlessEqual(expected, dedent(input)) def testBasicWithTabLeadersSpacesInside(self): input = \n\tHello\n\t World expected = \nHello\n World self.failUnlessEqual(expected, dedent(input, False)) def testAllTabs(self): input = \t\tHello\n\tWorld expected = \tHello\nWorld self.failUnlessEqual(expected, dedent(input, False)) def testFirstLineNotIndented(self): input = Hello\n\tWorld expected = input self.failUnlessEqual(expected, dedent(input, False)) def testMixedTabsAndSpaces(self): input = \t Hello\n \tWorld expected = \t Hello\n \tWorld self.failUnlessEqual(expected, dedent(input, False)) if __name__ == '__main__': unittest.main() -tom! It this works, good for you. I can't say I understand your objective. (You dedent common leading tabs, except if preceded by common leading spaces (?)). Neither do I understand the existence of indentations made up of tabs mixed with spaces, but that is another topic. I have been wasting a lot of time with things of this nature coding away before forming a clear conception in my mind of what my code was supposed to accomplish. Sounds stupid. But many problems seem trivial enough at first sight to create the illusion of perfect understanding. The encounter with the devil in the details can be put off but not avoided. Best to get it over with from the start and write an exhaustive formal description of the problem. Follows an exhaustive formal description of the rules for its solution. The rules can then be morphed into code in a straightforward manner. In other words, coding should be the translation of a logical system into a language a machine understands. It should not be the construction of the logical system. This, anyway
Re: textwrap.dedent replaces tabs?
Tom Plunket wrote: Frederic Rentsch wrote: Well, there is that small problem that there are leading tabs that I want stripped. I guess I could manually replace all tabs with eight spaces (as opposed to 'correct' tab stops), and then replace them when done, but it's probably just as easy to write a non-destructive dedent. This should do the trick: Dedent = re.compile ('^\s+') for line in lines: print Dedent.sub ('', line) The fact that this doesn't do what dedent() does makes it not useful. Stripping all leading spaces from text is as easy as calling lstrip() on each line: My goodness! How right your are. text = '\n'.join([line.lstrip() for line in text.split('\n')]) alas, that isn't what I am looking for, nor is that what textwrap.dedent() is intended to do. -tom! Following a call to dedent () it shouldn't be hard to translate leading groups of so many spaces back to tabs. But this is probably not what you want. If I understand your problem, you want to restore the dedented line to its original composition if spaces and tabs are mixed and this doesn't work because the information doesn't survive dedent (). Could the information perhaps be passed around dedent ()? Like this: make a copy of your lines and translate the copy's tabs to so many (8?) marker bytes (e.g. ascii 0). Dedent the originals. Left-strip each of the marked line copies to the length of its dedented original and translate the marked groups back to tabs. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: textwrap.dedent replaces tabs?
Tom Plunket wrote: CakeProphet wrote: Hmmm... a quick fix might be to temporarily replace all tab characters with another, relatively unused control character. MyString = MyString.replace(\t, chr(1)) MyString = textwrap.dedent(MyString) MyString = MyString.replace(chr(1), \t) Of course... this isn't exactly safe, but it's not going to be fatal, if it does mess something up. As long as you don't expect receiving any ASCII 1 characters. Well, there is that small problem that there are leading tabs that I want stripped. I guess I could manually replace all tabs with eight spaces (as opposed to 'correct' tab stops), and then replace them when done, but it's probably just as easy to write a non-destructive dedent. It's not that I don't understand /why/ it does it; indeed I'm sure it does this so you can mix tabs and spaces in Python source. Why anyone would intentionally do that, though, I'm not sure. ;) -tom! This should do the trick: Dedent = re.compile ('^\s+') for line in lines: print Dedent.sub ('', line) Frederic --- Testing: text = s = ''' # Dedent demo No indent Three space indent \tOne tab indent \t\tThree space, two tab indent \t \tOne tab, two space, one tab indent with two tabs here \t\t''' print text print s # Dedent demo No indent Three space indent One tab indent Three space - two tab indent One tab - two spaces - one tab indent with two tabs here for line in text.splitlines (): print Dedent.sub ('', line) # Dedent demo No indent Three space indent One tab indent Three space - two tab indent One tab - two spaces - one tab indent with two tabs here --- -- http://mail.python.org/mailman/listinfo/python-list
Re: Python spam?
Hendrik van Rooyen wrote: Aahz [EMAIL PROTECTED] wrote: Anyone else getting Python-related spam? So far, I've seen messages from Barry Warsaw and Skip Montanaro (although of course header analysis proves they didn't send it). -- not like that - just the normal crud from people giving me get rich quick tips on the stock market that is aimed at mobilising my money to follow theirs to help influence the price of a share... - Hendrik ...which I noticed works amazingly well in many cases, looking at the charts. which, again, means that the trick isn't likely to fizzle out soon as others have with victims getting wise to it. Getting feathers plucked in this game isn't a turn-off. It's an opportunity to join the pluckers by speeding up one's turnover at the expense of the slowpokes. Like pyramid sales this it is a self-generating market. This game, at least, isn't unethical, other than clogging the internet with reckless traffic. I've been asking myself why it seems so difficult to backtrace such obtrusive, if not criminal, traffic to the source and squash it there. Perhaps some knowledgeable volunteer would share his insights. Perhaps stalking con artists could be another interest group. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: splitting a long string into a list
ronrsr wrote: still having a heckuva time with this. here's where it stand - the split function doesn't seem to work the way i expect it to. longkw1,type(longkw): Agricultural subsidies; Foreign aid;Agriculture; Sustainable Agriculture - Support; Organic Agriculture; Pesticides, US, Childhood Development, Birth Defects; type 'list' 1 longkw.replace(',',';') Agricultural subsidies; Foreign aid;Agriculture; Sustainable Agriculture - Support; Organic Agriculture; Pesticides, US, Childhood Development kw = longkw.split(; ,)#kw is now a list of len 1 kw,typekw= ['Agricultural subsidies; Foreign aid;Agriculture; Sustainable Agriculture - Support; Organic Agriculture; Pesticides, US, Childhood Development, Birth Defects; Toxic Chemicals;Antibiotics, Animals;Agricultural Subsidies what I would like is to break the string into a list of the delimited words, but have had no luck doing that - I thought split wuld do that, but it doens't. bests, -rsr- import SE# http://cheeseshop.python.org/pypi/SE/2.3 Split_Marker = SE.SE (' ,=| ;=| ')# Translates both ',' and ';' into an arbitrary split mark ('|') for item in Split_Marker (longstring).split ('|'): print item Agricultural subsidies Foreign aidAgriculture Sustainable Agriculture - Support Organic Agriculture ... etc. To get rid of the the leading space on some lines simply add corresponding replacements. SE does any number of substitutions in one pass. Defining them is a simple matter of writing them up in one single string from which the translator object is made: Split_Marker = SE.SE (' ,=| ;=| , =| ; =| ') for item in Split_Marker (longstring).split ('|'): print item Agricultural subsidies Foreign aidAgriculture Sustainable Agriculture - Support Organic Agriculture Regards Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: utf - string translation
Dan wrote: On 22 nov, 22:59, John Machin [EMAIL PROTECTED] wrote: processes (Vigenère) So why do you want to strip off accents? The history of communication has several examples of significant difference in meaning caused by minute differences in punctuation or accents including one of which you may have heard: a will that could be read (in part) as either a chacun d'eux million francs or a chacun deux million francs with the remainder to a 3rd party. of course. My purpose is not doing something realistic on a cryptographic view. It's for learning rudiments of programming. In fact, coding characters is a kind of cryptography I mean, sometimes, when friends can't read an email because of the characters used... I wanted to strip off accents because I use the frequences of the charactacters. If I only have 26 char, it's more easy to analyse (the text can be shorter for example) Try this: from_characters = '\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xd9\xda\xdb\xdc\xdd\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xff\xe7\xe8\xe9\xea\xeb' to_characters = 'AAACDNOOYaaaonooyyc' translation_table = string.maketrans (from_characters, to_characters) translated_string = string.translate (original_string, translation_table) Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: multi split function taking delimiter list
Paddy wrote: Paddy wrote: Paddy wrote: [EMAIL PROTECTED] wrote: Hi, I'm looking for something like: multi_split( 'a:=b+c' , [':=','+'] ) returning: ['a', ':=', 'b', '+', 'c'] whats the python way to achieve this, preferably without regexp? Thanks. Martin I resisted my urge to use a regexp and came up with this: from itertools import groupby s = 'apple=blue+cart' [''.join(g) for k,g in groupby(s, lambda x: x in '=+')] ['apple', '=', 'blue', '+', 'cart'] For me, the regexp solution would have been clearer, but I need to stretch my itertools skills. - Paddy. Arghhh! No colon! Forget the above please. - Pad. With colon: from itertools import groupby s = 'apple:=blue+cart' [''.join(g) for k,g in groupby(s,lambda x: x in ':=+')] ['apple', ':=', 'blue', '+', 'cart'] - Pad. Automatic grouping may or may not work as intended. If some subsets should not be split, the solution raises a new problem. I have been demonstrating solutions based on SE with such frequency of late that I have begun to irritate some readers and SE in sarcastic exaggeration has been characterized as the 'Solution of Everything'. With some trepidation I am going to demonstrate another SE solution, because the truth of the exaggeration is that SE is a versatile tool for handling a variety of relatively simple problems in a simple, straightforward manner. test_string = 'a:=b+c: apple:=blue:+cart'' SE.SE (':\==/:\=/ +=/+/')(test_string).split ('/') # For repeats the SE object would be assigned to a variable ['a', ':=', 'b', '+', 'c: apple', ':=', 'blue:', '+', 'cart'] This is a nuts-and-bolts approach. What you do is what you get. What you want is what you do. By itself SE doesn't do anything but search and replace, a concept without a learning curve. The simplicity doesn't suggest versatility. Versatility comes from application techniques. SE is a game of challenge. You know the result you want. You know the pieces you have. The game is how to get the result with the pieces using search and replace, either per se or as an auxiliary, as in this case for splitting. That's all. The example above inserts some appropriate split mark ('/'). It takes thirty seconds to write it up and see the result. No need to ponder formulas and inner workings. If you don't like what you see you also see what needs to be changed. Supposing we should split single colons too, adding the corresponding substitution and verifying the effect is a matter of another ten seconds: SE.SE (':\==/:\=/ +=/+/ :=/:/')(test_string).split ('/') ['a', ':=', 'b', '+', 'c', ':', ' apple', ':=', 'blue', ':', '', '+', 'cart'] Now we see an empty field we don't like towards the end. Why? SE.SE (':\==/:\=/ +=/+/ :=/:/')(test_string) 'a/:=/b/+/c/:/ apple/:=/blue/://+/cart' Ah! It's two slashes next to each other. No problem. We de-multiply double slashes in a second pass: SE.SE (':\==/:\=/ +=/+/ :=/:/ | //=/')(test_string).split ('/') ['a', ':=', 'b', '+', 'c', ':', ' apple', ':=', 'blue', ':', '+', 'cart'] On second thought the colon should not be split if a plus sign follows: SE.SE (':\==/:\=/ +=/+/ :=/:/ :+=:/+/ | //=/')(test_string).split ('/') ['a', ':=', 'b', '+', 'c', ':', ' apple', ':=', 'blue:', '+', 'cart'] No, wrong again! 'Colon-plus' should be exempt altogether. And no spaces please: SE.SE (':\==/:\=/ +=/+/ :=/:/ :+=:+ = | //=/')(test_string).split ('/') ['a', ':=', 'b', '+', 'c', ':', 'apple', ':=', 'blue:+cart'] etc. It is easy to get carried away and to forget that SE should not be used instead of Python's built-ins, or to get carried away doing contextual or grammar processing explicitly, which gets messy very fast. SE fills a gap somewhere between built-ins and parsers. Stream editing is not a mainstream technique. I believe it has the potential to make many simple problems trivial and many harder ones simpler. This is why I believe the technique deserves more attention, which, again, may explain the focus of my posts. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Seeking assistance - string processing.
[EMAIL PROTECTED] wrote: I've been working on some code to search for specific textstrings and act upon them insome way. I've got the conversion sorted however there is 1 problem remaining. I am trying to work out how to make it find a string like this === and when it has found it, I want it to add === to the end of the line. For example. The text file contains this: ===Heading and I am trying to make it be processed and outputted as a .dat file with the contents ===Heading=== Here's the code I have got so far. import string import glob import os mydir = os.getcwd() newdir = mydir#+\\Test\\; for filename in glob.glob1(newdir,*.txt): #print This is an input file: + filename fileloc = newdir+\\+filename #print fileloc outputname = filename outputfile = string.replace(outputname,'.txt','.dat') #print filename #print a print This is an input file: + filename + . Output file: +outputfile #temp = newdir + \\ + outputfile #print temp fpi = open(fileloc); fpo = open(outputfile,w+); output_lines = [] lines = fpi.readlines() for line in lines: if line.rfind() is not -1: new = line.replace(,) elif line.rfind(img:) is not -1: new = line.replace(img:,[[Image:) elif line.rfind(.jpg) is not -1: new = line.replace(.jpg,.jpg]]) elif line.rfind(.gif) is not -1: new = line.replace(.gif,.gif]]) else: output_lines.append(line); continue output_lines.append(new); for line in output_lines: fpo.write(line) fpi.close() fpo.flush() fpo.close() I hope this gets formatted correctly :-p Cheers, hope you can help. Here's a suggestion: import SE Editor = SE.SE ('== img:=[[Image: .jpg=.jpg]] .gif=.gif]]') Editor (' img: .jpg .gif')# See if it works ' [[Image: .jpg]] .gif]]' It works. (Add in other replacements if the need arises.) Works linewise for line in f: new_line = Editor (line) ... Or filewise, which comes in handy in your case: for in_filename in glob.glob (newdir+'/*.txt'): out_filename = in_filename.replace ('.txt','.dat') Editor (in_filename, out_filename) See if that helps. Find SE here: http://cheeseshop.python.org/pypi/SE/2.3 Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Character encoding
mp wrote: I have html document titles with characters like gt;, nbsp;, and #135. How do I decode a string with these values in Python? Thanks This is definitely the most FAQ. It comes up about once a week. The stream-editing way is like this: import SE HTM_Decoder = SE.SE ('htm2iso.se') # Include path test_string = '''I have html document titles with characters like gt;, nbsp;, and #135;. How do I decode a string with these values in Python?''' print HTM_Decoder (test_string) I have html document titles with characters like , , and ‡. How do I decode a string with these values in Python? An SE object does files too. HTM_Decoder ('with_codes.txt', 'translated_codes.txt') # Include path You could download SE from - http://cheeseshop.python.org/pypi/SE/2.3. The translation definitions file htm2iso.se is included. If you open it in your editor, you can see how to write your own definition files for other translation tasks you may have some other time. Regards Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: string to list of numbers conversion
[EMAIL PROTECTED] wrote: Hi, I have a string '((1,2), (3,4))' and I want to convert this into a python tuple of numbers. But I do not want to use eval() because I do not want to execute any code in that string and limit it to list of numbers. Is there any alternative way? Thanks. Suresh s = '((1,2), (3,4))' separators = re.compile ('\(\s*\(|\)\s*,\s*\(|\)\s*\)') tuple ([(float (n[0]), float (n[1])) for n in [pair.split (',') for pair in separators.split (s) if pair]]) ((1.0, 2.0), (3.0, 4.0)) Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: ANN: SE 2.3. Available now
Fredrik Lundh wrote: Frederic Rentsch wrote: And here's the proof I am being perceived as a nuisance. I apologize, keeping to myself that I don't care. since you're constantly targeting newbies, and are hawking your stuff also for things for which there are simple and efficient solutions available in Python's standard library, your behavior could be seen as more than just a nuisance. /F Thank you for making me aware of it. I totally agree with you that inefficient complexity should never replace efficient simplicity. SE, in fact, is much more a convenient interface complement than a stand-alone tool and as such meant to cooperate with the available Python idiom. I used this forum to connect with real-life problems, which I believe is one of its main purposes. Testing the envelope of my 'stuff' I would almost certainly have overstretched it on occasion. And again, what's wrong with this absolutely normal development process? And what better environment could there be for it than an interest group like this one where experts like yourself offer direction? I am not targeting newbies (whatever that is). I am not targeting at all. I invite response. You had cause to respond as this message of yours reveals. But you didn't respond and now your are angry with me for it. So, thanks again for the information. Your comments are always welcome. I understand your style as an expression of your personality. Belligerence passes my notice if I don't see what I have to do with it. Regards Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: SE 2.3 temporarily unavailable. Cheese shop defeats upload with erratic behavior. Urgently requesting help.
jim-on-linux wrote: Frederic, I've been trying to get back into my package in the Cheese Shop for over a year. The phone company changed my e:mail address and to make a long and frustrating story short I can't get back into the Cheese Shop to make changes to my file. Time is money. At some time you have to consider if it is worth it. At least you have the name of your program listed. I wish I could be more helpfull. I'll watch the responses you get from others. Good Luck, jim-on-linux http://www.inqvista.com On Thursday 02 November 2006 09:00, you wrote: Some time ago I had managed to upload a small package to the Cheese Shop using the data entry template. Uploading is in two steps: first the text then the package file. When I had a new version it went like this: The new text made a new page, but the new file went to the old snip Thanks for letting me know that I am not alone. Do you know of an alternative to the Cheese Shop? Frederic -- http://mail.python.org/mailman/listinfo/python-list
ANN: SE 2.3. Available now
A few Cheese Shop upload problems have been solved with the help of this creative group. Thank you all! Version 2.2 beta should be phased out. It has a functional defect, missing matches with a very low statistical probability. Version 2.3 has this fixed. Download URL: http://cheeseshop.python.org/pypi/SE/2.3 A list of possible handling improvements is being made to be incorporated in the next version, One major flaw of the interface design came to light the other day when a user reported a non-functioning Editor Object made with a file name. If the constructor cannot find the file it records the fact in the object's log without making the user aware that his Editor Object is incomplete or altogether devoid of substitutions. His obvious conclusion is that the damn thing isn't working right. Compile errors should certainly be reported at compile time. The next version will send all messages being logged also to stderr by default. The thing to do with the current version, if it appears to malfunction, is to inspect the log and the compiled substitutions. Editor = SE.SE ('operators.se') Editor.show_log () Fri Nov 03 12:49:17 2006 - Compiler - Ignoring single word 'operators.se'. Not an existing file 'operators.se'. Editor = SE.SE ('se/operators.se') # path was missing Editor.show_log () (Log is empty. All is well.) Editor.show (show_translators = 1) (snip) Single-Byte Targets 1: ||-|LT| 2: ||-|GT| Multi-Byte Targets 3: ||-|AND| 4: -|OR| etc... The display makes definition errors conspicuous. Missing definitions indicate malformed or redefined (overwritten) ones. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: SE
C or L Smith wrote: Hello, I'm evaluating different methods of handling a transliteration (from an ascii-based representation of the devanagari/indian script to a romanized representation). I found SE and have been working with it today. One thing that I ran into (that I don't see a reason for right off) is the behavior where a single period just gets eaten and no output is produced: import SE s=SE.SE('.=period') s('A.') 'Aperiod' s('.') It's not the fact that it's a single character target that is causing the problem: s=SE.SE('x=y') s('x') 'y' I also tried the following: s=SE.SE('(46)=dot') s('A.') 'Adot' s('.') Am I missing something? /chris No, you are not missing anything. Quite on the contrary. You caught something! Thanks for the report. Here's the patch: Line 343 in SEL.py is: if name == '': Make it:if name.replace ('.', '') == '': In Version 2.2 it's line 338. But Version 2.2 should be phased out anyway. The problem had to do with the automatic typing of the input data that tells string input from file names, which of course are also strings. The test is done by os.stat (). If it says an input string is an existing file, then that file is translated. Admittedly this is not a very robust mechanism. In practice, though, I have never had a problem with it, because input data just about never are single words. If names of existing files are the object of a translation they would be passed all together and be unambiguously recognized as a string. To translate a single file name SE is hardly a means of choice, but it could still be done if the file name is given a leading space. Now, if a single dot (or multiple dots) come along, os.stat does not raise an error and that results in a typing error at that point. The patch above takes care of that. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: ANN: SE 2.3. Available now
Gary Herron wrote: Frederic Rentsch wrote: A few Cheese Shop upload problems have been solved with the help of this creative group. Thank you all! Version 2.2 beta should be phased out. It has a functional defect, missing matches with a very low statistical probability. Version 2.3 has this fixed. Download URL: http://cheeseshop.python.org/pypi/SE/2.3 As a matter of polite netiquette, a message like this really ought to have a paragraph telling us what SE *is*.(Unless it's a secret :-)) Thanks for the inquiry. I've been hawking this thing so persistently of late that I'm afraid to start being perceived as a nuisance. SE is a stream editor that is particularly easy and fast to use. A summary of its characteristics is only a click away at the URL a few lines up from this line. Frederic A list of possible handling improvements is being made to be incorporated in the next version, One major flaw of the interface design came to light the other day when a user reported a non-functioning Editor Object made with a file name. If the constructor cannot find the file it records the fact in the object's log without making the user aware that his Editor Object is incomplete or altogether devoid of substitutions. His obvious conclusion is that the damn thing isn't working right. Compile errors should certainly be reported at compile time. The next version will send all messages being logged also to stderr by default. The thing to do with the current version, if it appears to malfunction, is to inspect the log and the compiled substitutions. Editor = SE.SE ('operators.se') Editor.show_log () Fri Nov 03 12:49:17 2006 - Compiler - Ignoring single word 'operators.se'. Not an existing file 'operators.se'. Editor = SE.SE ('se/operators.se') # path was missing Editor.show_log () (Log is empty. All is well.) Editor.show (show_translators = 1) (snip) Single-Byte Targets 1: ||-|LT| 2: ||-|GT| Multi-Byte Targets 3: ||-|AND| 4: -|OR| etc... The display makes definition errors conspicuous. Missing definitions indicate malformed or redefined (overwritten) ones. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: ANN: SE 2.3. Available now
Fredrik Lundh wrote: Gary Herron wrote: As a matter of polite netiquette, a message like this really ought to have a paragraph telling us what SE *is*.(Unless it's a secret :-)) nah, if you've spent more than five minutes on c.l.python lately, you'd noticed that it's the Solution to Everything (up there with pyparsing, I think). /F And here's the proof I am being perceived as a nuisance. I apologize, keeping to myself that I don't care. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: unescape HTML entities
Rares Vernica wrote: Hi, Nice module! I downloaded 2.3 and I started to play with it. The file names have funny names, they are all caps, including extension. For example the main module file is SE.PY. Is you try import SE it will not work as Python expects the file extension to be py. Thanks, Ray Frederic Rentsch wrote: Rares Vernica wrote: Hi, How can I unescape HTML entities like nbsp;? I know about xml.sax.saxutils.unescape() but it only deals with amp;, lt;, and gt;. Also, I know about htmlentitydefs.entitydefs, but not only this dictionary is the opposite of what I need, it does not have nbsp;. It has to be in python 2.4. Thanks a lot, Ray One way is this: import SE # Download from http://cheeseshop.python.org/pypi/SE/2.2%20beta SE.SE ('HTM2ISO.se')('input_file_name', 'output_file_name')# HTM2ISO.se is included 'output_file_name' For repeated translations the SE object would be assigned to a variable: HTM_Decoder = SE.SE ('HTM2ISO.se') SE objects take and return strings as well as file names which is useful for translating string variables, doing line-by-line translations and for interactive development or verification. A simple way to check a substitution set is to use its definitions as test data. The following is a section of the definition file HTM2ISO.se: test_string = ''' oslash;=(xf8) # 248 f8 ugrave;=(xf9) # 249 f9 uacute;=(xfa) # 250 fa ucirc;=(xfb)# 251 fb uuml;=(xfc) # 252 fc yacute;=(xfd) # 253 fd thorn;=(xfe)# 254 fe #233;=(xe9) #234;=(xea) #235;=(xeb) #236;=(xec) #237;=(xed) #238;=(xee) #239;=(xef) ''' print HTM_Decoder (test_string) ø=(xf8) # 248 f8 ù=(xf9) # 249 f9 ú=(xfa) # 250 fa û=(xfb)# 251 fb ü=(xfc) # 252 fc ý=(xfd) # 253 fd þ=(xfe)# 254 fe é=(xe9) ê=(xea) ë=(xeb) ì=(xec) í=(xed) î=(xee) ï=(xef) Another feature of SE is modularity. strip_tags = ''' ~(.|\x0a)*?~=(9) # one tag to one tab ~!--(.|\x0a)*?--~=(9) # one comment to one tab | # run ~\x0a[ \x09\x0d\x0a]*~=(x0a) # delete empty lines ~\t+~=(32) # one or more tabs to one space ~\x20\t+~=(32) # one space and one or more tabs to one space ~\t+\x20~=(32) # one or more tab and one space to one space ''' HTM_Stripper_Decoder = SE.SE (strip_tags + ' HTM2ISO.se ') # Order doesn't matter If you write 'strip_tags' to a file, say 'STRIP_TAGS.se' you'd name it together with HTM2ISO.se: HTM_Stripper_Decoder = SE.SE ('STRIP_TAGS.se HTM2ISO.se') # Order doesn't matter Or, if you have two SE objects, one for stripping tags and one for decoding the ampersands, you can nest them like this: test_string = p class=MsoNormal style='line-height:110%'iReneacute;/i est un garccedil;on qui paraicirc;t plus acirc;geacute;. /p print Tag_Stripper (HTM_Decoder (test_string)) René est un garçon qui paraît plus âgé. Nesting works with file names too, because file names are returned: Tag_Stripper (HTM_Decoder ('input_file_name'), 'output_file_name') 'output_file_name' Frederic Arrrgh! Did it again capitalizing extensions. We had solved this problem and here we have it again. I am so sorry. Fortunately it isn't hard to solve, renaming the files once one identifies the problem, which you did. I shall change the upload within the next sixty seconds. Frederic I'm glad you find it useful. -- http://mail.python.org/mailman/listinfo/python-list
SE 2.3 temporarily unavailable. Cheese shop defeats upload with erratic behavior. Urgently requesting help.
Some time ago I had managed to upload a small package to the Cheese Shop using the data entry template. Uploading is in two steps: first the text then the package file. When I had a new version it went like this: The new text made a new page, but the new file went to the old page. The old page then had both files and all attempts at uploading the new file to the new page failed with the error message that a file could not be uploaded if it was already there. So I let it go and handed out the url of the old page, figuring that given the choice of two versions, picking the latest one was well within the capabilities of anyone. One downloader just now made me aware that the new version had misspelled extensions 'PY'. They should be lower case. So I fixed it an tried to exchange the file. One hour later I have three text pages, headed V2,2beta, V2,2beta/V2.3 and V2.3. The first (oldest) page has the old package file. The two other pages have no files. The new version package is gone, because, prior to re-uploading I was asked to delete it. The re-upload fails on all three pages with the message: 'Error processing form, invalid distribution file'. The file is a zip file made exactly the way I had made and uploaded the ones before. I am banging my real head against the proverbial wall. This thing definitely behaves erratically and I see no alternative other than to stop banging and go to the gym to take my anger out at machines and when I come back in an hour, I wish a kind, knowledgeable soul will have posted some good advice on how to vanquish such stubborn obstinacy. I have disseminated the url and the thought that someone might show up there and not find the promised goods make me really unhappy. Until such time as this upload is made, I will be happy to send SE-2.3 out off list by request. Infinite thanks Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: unescape HTML entities
Rares Vernica wrote: Hi, I downloades 2.2 beta, just to be sure I have the same version as you specify. (The file names are no longer funny.) Anyway, it does not seem to do as you said: In [14]: import SE In [15]: SE.version --- SE.version() Out[15]: 'SE 2.2 beta - SEL 2.2 beta' In [16]: HTM_Decoder = SE.SE ('HTM2ISO.se') In [17]: test_string = ''' : oslash;=(xf8) # 248 f8 : ugrave;=(xf9) # 249 f9 : uacute;=(xfa) # 250 fa : ucirc;=(xfb)# 251 fb : uuml;=(xfc) # 252 fc : yacute;=(xfd) # 253 fd : thorn;=(xfe)# 254 fe : #233;=(xe9) : #234;=(xea) : #235;=(xeb) : #236;=(xec) : #237;=(xed) : #238;=(xee) : #239;=(xef) : ''' In [18]: print HTM_Decoder (test_string) oslash;=(xf8) # 248 f8 ugrave;=(xf9) # 249 f9 uacute;=(xfa) # 250 fa ucirc;=(xfb)# 251 fb uuml;=(xfc) # 252 fc yacute;=(xfd) # 253 fd thorn;=(xfe)# 254 fe #233;=(xe9) #234;=(xea) #235;=(xeb) #236;=(xec) #237;=(xed) #238;=(xee) #239;=(xef) In [19]: Thanks, Ray Frederic Rentsch wrote: Rares Vernica wrote: Hi, How can I unescape HTML entities like nbsp;? I know about xml.sax.saxutils.unescape() but it only deals with amp;, lt;, and gt;. Also, I know about htmlentitydefs.entitydefs, but not only this dictionary is the opposite of what I need, it does not have nbsp;. It has to be in python 2.4. Thanks a lot, Ray One way is this: import SE # Download from http://cheeseshop.python.org/pypi/SE/2.2%20beta SE.SE ('HTM2ISO.se')('input_file_name', 'output_file_name')# HTM2ISO.se is included 'output_file_name' For repeated translations the SE object would be assigned to a variable: HTM_Decoder = SE.SE ('HTM2ISO.se') SE objects take and return strings as well as file names which is useful for translating string variables, doing line-by-line translations and for interactive development or verification. A simple way to check a substitution set is to use its definitions as test data. The following is a section of the definition file HTM2ISO.se: test_string = ''' oslash;=(xf8) # 248 f8 ugrave;=(xf9) # 249 f9 uacute;=(xfa) # 250 fa ucirc;=(xfb)# 251 fb uuml;=(xfc) # 252 fc yacute;=(xfd) # 253 fd thorn;=(xfe)# 254 fe #233;=(xe9) #234;=(xea) #235;=(xeb) #236;=(xec) #237;=(xed) #238;=(xee) #239;=(xef) ''' print HTM_Decoder (test_string) ø=(xf8) # 248 f8 ù=(xf9) # 249 f9 ú=(xfa) # 250 fa û=(xfb)# 251 fb ü=(xfc) # 252 fc ý=(xfd) # 253 fd þ=(xfe)# 254 fe é=(xe9) ê=(xea) ë=(xeb) ì=(xec) í=(xed) î=(xee) ï=(xef) Another feature of SE is modularity. strip_tags = ''' ~(.|\x0a)*?~=(9) # one tag to one tab ~!--(.|\x0a)*?--~=(9) # one comment to one tab | # run ~\x0a[ \x09\x0d\x0a]*~=(x0a) # delete empty lines ~\t+~=(32) # one or more tabs to one space ~\x20\t+~=(32) # one space and one or more tabs to one space ~\t+\x20~=(32) # one or more tab and one space to one space ''' HTM_Stripper_Decoder = SE.SE (strip_tags + ' HTM2ISO.se ') # Order doesn't matter If you write 'strip_tags' to a file, say 'STRIP_TAGS.se' you'd name it together with HTM2ISO.se: HTM_Stripper_Decoder = SE.SE ('STRIP_TAGS.se HTM2ISO.se') # Order doesn't matter Or, if you have two SE objects, one for stripping tags and one for decoding the ampersands, you can nest them like this: test_string = p class=MsoNormal style='line-height:110%'iReneacute;/i est un garccedil;on qui paraicirc;t plus acirc;geacute;. /p print Tag_Stripper (HTM_Decoder (test_string)) René est un garçon qui paraît plus âgé. Nesting works with file names too, because file names are returned: Tag_Stripper (HTM_Decoder ('input_file_name'), 'output_file_name') 'output_file_name' Frederic Ray, I am sorry you're having a problem. I cannot duplicate it. It works fine here. I suspect that SE.SE doesn't find your file HTM2ISO.SE. Do this: HTM_Decoder = SE.SE ('HTM2ISO.SE') HTM_Decoder.show_log () Thu Nov 02 15:15:39 2006 - Compiler - Ignoring single word 'HTM2ISO.SE'. Not an existing file 'HTM2ISO.SE'. If you see this, then you might have forgotten to include the path with the file name. Rather than getting an old version, you could just have renamed the to py-files. Version 2.3 has some minor bugs corrected. I fixed the names and tried to re-upload to the Cheese Shop and the damn thing stubbornly refuses the upload after having required that I delete the file I was going to replacing. So it isn't there anymore and the replacement isn't there yet. I'll
Re: Where do nested functions live?
Rob Williscroft wrote: Frederic Rentsch wrote in news:mailman.1556.1162316571.11739.python- [EMAIL PROTECTED] in comp.lang.python: Rob Williscroft wrote: Frederic Rentsch wrote in news:mailman.1536.1162292996.11739.python- Rob Williscroft wrote: Frederic Rentsch wrote in news:mailman.1428.1162113628.11739.python- [snip] Here I'm lost. What's the advantage of this? It looks more convoluted. I'll agree that having to explicitly define a namespace class first does add some convolution. But if you refer to having to prefix you outer variables with scope. then this would be the same as claiming that the explict use of self is convoluted, which is a valid opinion, so fair enough, but I can't say that I agree. I didn't mean to call into question. I didn't understand the advantage of the added complexity of your second example over the first. Ok, I missed your point, as for the second example it was an attempt to show that further refactoring from a function with local functions that are sharing some state via the scope object, to a class with methods that share state via the instance, is a matter of editing a few lines. This is useful when a function grows too large (for some value of too large). As an added bonus you get to use the same thechniques with both styles of coding. [snip] Rob. Rob, Thanks a lot for your input. I'll have to digest that. Another question I had and forgot was this: Since we have a class that goes out of scope when the function returns, and we don't need more than one instance, why bother to make an instance? Why not use the class object itself? def whatever( new_ms ): class scope ( object ): def inner(): scope.mseconds = new_ms - s * 1000 m, scope.seconds = divmod (s, 60) h, scope.minutes = divmod (m, 60) d, scope.hours = divmod (h, 24) scope.weeks, scope.days = divmod (d, 7) Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Where do nested functions live?
Rob Williscroft wrote: Frederic Rentsch wrote in news:mailman.1428.1162113628.11739.python- [EMAIL PROTECTED] in comp.lang.python: def increment_time (interval_ms): outer weeks, days, hours, minutes, seconds, mseconds # 'outer' akin to 'global' (...) mseconds = new_ms - s * 1000# Assignee remains outer m, seconds = divmod (s, 60) h, minutes = divmod (m, 60) d, hours = divmod (h, 24) weeks, days = divmod (d, 7) # No return necessary The call would now be: increment_time (msec) # No reassignment necessary Hope this makes sense Yes it does, but I prefer explicit in this case: def whatever( new_ms ): class namespace( object ): pass scope = namespace() def inner(): scope.mseconds = new_ms - s * 1000 m, scope.seconds = divmod (s, 60) h, scope.minutes = divmod (m, 60) d, scope.hours = divmod (h, 24) scope.weeks, scope.days = divmod (d, 7) This is interesting. I am not too familiar with this way of using objects. Actually it isn't all that different from a list, because a list is also an object. But this way it's attribute names instead of list indexes which is certainly easier to work with. Very good! The only thing I find anoying is that I can't write: scope = object() Additionally if appropriate I can refactor further: def whatever( new_ms ): class namespace( object ): def inner( scope ): scope.mseconds = new_ms - s * 1000 m, scope.seconds = divmod (s, 60) h, scope.minutes = divmod (m, 60) d, scope.hours = divmod (h, 24) scope.weeks, scope.days = divmod (d, 7) scope = namespace() scope.inner() In short I think an outer keyword (or whatever it gets called) will just add another way of doing something I can already do, and potentially makes further refactoring harder. Here I'm lost. What's the advantage of this? It looks more convoluted. And speaking of convoluted, what about efficiency? There is much talk of efficiency on this forum. I (crudely) benchmark your previous example approximately three times slower than a simple inner function taking and returning three parameters. It was actually the aspect of increased efficiency that prompted me to play with the idea of allowing direct outer writes. Thats -2 import-this points already. Which ones are the two? Rob. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Where do nested functions live?
Rob Williscroft wrote: Frederic Rentsch wrote in news:mailman.1536.1162292996.11739.python- [EMAIL PROTECTED] in comp.lang.python: Rob Williscroft wrote: Frederic Rentsch wrote in news:mailman.1428.1162113628.11739.python- [EMAIL PROTECTED] in comp.lang.python: def whatever( new_ms ): class namespace( object ): pass scope = namespace() def inner(): scope.mseconds = new_ms - s * 1000 m, scope.seconds = divmod (s, 60) h, scope.minutes = divmod (m, 60) d, scope.hours = divmod (h, 24) scope.weeks, scope.days = divmod (d, 7) This is interesting. I am not too familiar with this way of using objects. Actually it isn't all that different from a list, because a list is also an object. But this way it's attribute names instead of list indexes which is certainly easier to work with. Very good! In short I think an outer keyword (or whatever it gets called) will just add another way of doing something I can already do, and potentially makes further refactoring harder. Here I'm lost. What's the advantage of this? It looks more convoluted. I'll agree that having to explicitly define a namespace class first does add some convolution. But if you refer to having to prefix you outer variables with scope. then this would be the same as claiming that the explict use of self is convoluted, which is a valid opinion, so fair enough, but I can't say that I agree. I didn't mean to call into question. I didn't understand the advantage of the added complexity of your second example over the first. It should also be noted that although I have to declare and create a scope object. My method doesn't require the attributes passed back from the inner function be pre-declared, should I during coding realise that I need to return another attribute I just assign it in the inner function and use it in the outer function. I would count that as less convoluted, YMMV. That is certainly a very interesting aspect. And speaking of convoluted, what about efficiency? There is much talk of efficiency on this forum. I (crudely) benchmark your previous example approximately three times slower than a simple inner function taking and returning three parameters. It was actually the aspect of increased efficiency that prompted me to play with the idea of allowing direct outer writes. Did you have optimisation turned on ? No. I did a hundred thousand loops over each in IDLE using xrange. As I see it there should be no reason an optimiser couldn't transform my code into the same code we might expect from your outer keyword example, as the scope object's type and attributes are all contained within (thus known to) the outer function defenition. I doubt that very much. The 'outer' keyword would give me the choice between two alternatives. Such a choice can hardly be automated. Wether CPython's optimiser does this or not, I don't know. Thats -2 import-this points already. Which ones are the two? Explicit is better than implicit. There should be one-- and preferably only one --obvious way to do it. Rob. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: How to convert nbsp; in a string to blank space?
一首诗 wrote: Oh, I didn't make myself clear. What I mean is how to convert a piece of html to plain text bu keep as much format as possible. Such as convert nbsp; to blank space and convert br to \r\n Gary Herron wrote: 一首诗 wrote: Is there any simple way to solve this problem? Yes, strings have a replace method: s = abcnbsp;def s.replace('nbsp;',' ') 'abc def' Also various modules that are meant to deal with web and xml and such have functions to do such operations. Gary Herron my_translations = ''' nbsp;= # br=\r\n BR=\r\n # Windows br=\n BR=\n # Linux # Add others to your heart's content ''' import SE # From http://cheeseshop.python.org/pypi/SE/2.2%20beta My_Translator = SE.SE (my_translations) print My_Translator ('ABCnbsp;DEFGbrXYZ') ABC DEFG XYZ SE can also strip tags and translate all HTM escapes and generally lets you do ad hoc translations in seconds. You just write them up, make an SE object from your text an run your data through it. As simple as that. If you wish further explanations, I'll be happy to explain. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Where do nested functions live?
Diez B. Roggisch wrote: If I may turn the issue around, I could see a need for an inner function to be able to access the variables of the outer function, the same way a function can access globals. Why? Because inner functions serve to de-multiply code segments one would otherwise need to repeat or to provide a code segment with a name suggestive of its function. In either case the code segment moved to the inner function loses contact with its environment, which rather mitigates its benefit. Maybe I'm dense here, but where is your point? Python has nested lexical scoping, and while some people complain about it's actual semantics, it works very well: def outer(): outer_var = 10 def inner(): return outer_var * 20 return inner print outer()() Diez My point is that an inner function operating on existing outer variables should be allowed to do so directly. Your example in its simplicity is unproblematic. Let us consider a case where several outer variables need to be changed: weeks = days = hours = minutes = seconds = 0 mseconds = 0.0 (code) # add interval in milliseconds have_ms = ((weeks * 7) + days) * 24) + hours) * 60) + minutes) * 60) + seconds) * 1000) + mseconds) new_ms = have_ms + interval_ms # reconvert s = new_ms / 1000.0 s = int (s) mseconds = new_ms - s * 1000 m, seconds = divmod (s, 60) h, minutes = divmod (m, 60) d, hours = divmod (h, 24) weeks, days = divmod (d, 7) (more code) At some later point I need to increment my units some more and probably will again a number of times. Clearly this has to go into a function. I make it an inner function, because the scope of its service happens to be local to the function in which it comes to live. It operates on existing variables of what is now its containing function. def increment_time (interval_ms): have_ms = ((weeks * 7) + days) * 24) + hours) * 60) + minutes) * 60) + seconds) * 1000) + mseconds) new_ms = have_ms + interval_ms # reconvert s = new_ms / 1000.0 s = int (s) ms -= s * 1000 # Was mseconds = new_ms - s * 1000 m, s = divmod (s, 60)# Was m, seconds = divmod (s, 60) h, m = divmod (m, 60)# Was h, minutes = divmod (m, 60) d, h = divmod (h, 24)# Was d, hours = divmod (h, 24) w, d = divmod (d, 7) # Was weeks, days = divmod (d, 7) return w, d, h, m, s, ms Functionizing I must change the names of the outer variables. Assigning to them would make them local, their outer namesakes would become invisible and I'd have to pass them all as arguments. Simpler is changing assignees names, retaining visibility and therefore not having to pass arguments. In either case I have to return the result for reassignment by the call. weeks, days, hours, minutes, seconds, milliseconds = increment_time (msec) This is a little like a shop where the mechanics have to get their tools and work pieces from the manager and hand them back to him when they're done. The following two examples are illustrations of my point. They are not proposals for 'improvement' of a language I would not presume to improve. def increment_time (interval_ms): outer weeks, days, hours, minutes, seconds, mseconds # 'outer' akin to 'global' (...) mseconds = new_ms - s * 1000# Assignee remains outer m, seconds = divmod (s, 60) h, minutes = divmod (m, 60) d, hours = divmod (h, 24) weeks, days = divmod (d, 7) # No return necessary The call would now be: increment_time (msec) # No reassignment necessary Hope this makes sense Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: unescape HTML entities
Rares Vernica wrote: Hi, How can I unescape HTML entities like nbsp;? I know about xml.sax.saxutils.unescape() but it only deals with amp;, lt;, and gt;. Also, I know about htmlentitydefs.entitydefs, but not only this dictionary is the opposite of what I need, it does not have nbsp;. It has to be in python 2.4. Thanks a lot, Ray One way is this: import SE # Download from http://cheeseshop.python.org/pypi/SE/2.2%20beta SE.SE ('HTM2ISO.se')('input_file_name', 'output_file_name')# HTM2ISO.se is included 'output_file_name' For repeated translations the SE object would be assigned to a variable: HTM_Decoder = SE.SE ('HTM2ISO.se') SE objects take and return strings as well as file names which is useful for translating string variables, doing line-by-line translations and for interactive development or verification. A simple way to check a substitution set is to use its definitions as test data. The following is a section of the definition file HTM2ISO.se: test_string = ''' oslash;=(xf8) # 248 f8 ugrave;=(xf9) # 249 f9 uacute;=(xfa) # 250 fa ucirc;=(xfb)# 251 fb uuml;=(xfc) # 252 fc yacute;=(xfd) # 253 fd thorn;=(xfe)# 254 fe #233;=(xe9) #234;=(xea) #235;=(xeb) #236;=(xec) #237;=(xed) #238;=(xee) #239;=(xef) ''' print HTM_Decoder (test_string) ø=(xf8) # 248 f8 ù=(xf9) # 249 f9 ú=(xfa) # 250 fa û=(xfb)# 251 fb ü=(xfc) # 252 fc ý=(xfd) # 253 fd þ=(xfe)# 254 fe é=(xe9) ê=(xea) ë=(xeb) ì=(xec) í=(xed) î=(xee) ï=(xef) Another feature of SE is modularity. strip_tags = ''' ~(.|\x0a)*?~=(9) # one tag to one tab ~!--(.|\x0a)*?--~=(9) # one comment to one tab | # run ~\x0a[ \x09\x0d\x0a]*~=(x0a) # delete empty lines ~\t+~=(32) # one or more tabs to one space ~\x20\t+~=(32) # one space and one or more tabs to one space ~\t+\x20~=(32) # one or more tab and one space to one space ''' HTM_Stripper_Decoder = SE.SE (strip_tags + ' HTM2ISO.se ') # Order doesn't matter If you write 'strip_tags' to a file, say 'STRIP_TAGS.se' you'd name it together with HTM2ISO.se: HTM_Stripper_Decoder = SE.SE ('STRIP_TAGS.se HTM2ISO.se') # Order doesn't matter Or, if you have two SE objects, one for stripping tags and one for decoding the ampersands, you can nest them like this: test_string = p class=MsoNormal style='line-height:110%'iReneacute;/i est un garccedil;on qui paraicirc;t plus acirc;geacute;. /p print Tag_Stripper (HTM_Decoder (test_string)) René est un garçon qui paraît plus âgé. Nesting works with file names too, because file names are returned: Tag_Stripper (HTM_Decoder ('input_file_name'), 'output_file_name') 'output_file_name' Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Where do nested functions live?
Fredrik Lundh wrote: Frederic Rentsch wrote: At some later point I need to increment my units some more and probably will again a number of times. Clearly this has to go into a function. since Python is an object-based language, clearly you could make your counter into a self-contained object instead of writing endless amounts of code and wasting CPU cycles by storing what's really a *single* state in a whole bunch of separate variables. This is surely a good point I'll have to think about. in your specific example, you can even use an existing object: Of course. But my example wasn't about time. It was about the situation t = datetime.datetime.now() # increment t += datetime.timedelta(milliseconds=msec) print t.timetuple() # get the contents if you're doing this so much that it's worth streamlining the timedelta addition, you can wrap the datetime instance in a trivial class, and do t += 1500 # milliseconds when you need to increment the counter. This is a little like a shop where the mechanics have to get their tools and work pieces from the manager and hand them back to him when they're done. that could of course be because when he was free to use whatever tool he wanted, he always used a crowbar, because he hadn't really gotten around to read that tool kit for dummies book. No mechanic always uses a crowbar. He'd use it just once--with the same employer. /F -- http://mail.python.org/mailman/listinfo/python-list
Re: Where do nested functions live?
Fredrik Lundh wrote: Steven D'Aprano wrote: I defined a nested function: def foo(): def bar(): return bar return foo + bar() which works. Knowing how Python loves namespaces, I thought I could do this: foo.bar() Traceback (most recent call last): File stdin, line 1, in ? AttributeError: 'function' object has no attribute 'bar' but it doesn't work as I expected. where do nested functions live? in the local variable of an executing function, just like the variable bar in the following function: def foo(): bar = who am I? where do I live? (yes, an inner function is *created* every time you execute the outer function. but it's created from prefabricated parts, so that's not a very expensive process). /F If I may turn the issue around, I could see a need for an inner function to be able to access the variables of the outer function, the same way a function can access globals. Why? Because inner functions serve to de-multiply code segments one would otherwise need to repeat or to provide a code segment with a name suggestive of its function. In either case the code segment moved to the inner function loses contact with its environment, which rather mitigates its benefit. If I have an inner function that operates on quite a few outer variables it would be both convenient and surely more efficient, if I could start the inner function with a declaration analogous to a declaration of globals, listing the outer variables which I wish to remain writable directly. I guess I could put the outer variables into a list as argument to the inner function. But while this relieves the inner function of returning lots of values it burdens the outer function with handling the list which it wouldn't otherwise need. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Search Replace
DataSmash wrote: Hello, I need to search and replace 4 words in a text file. Below is my attempt at it, but this code appends a copy of the text file within itself 4 times. Can someone help me out. Thanks! # Search Replace file = open(text.txt, r) text = file.read() file.close() file = open(text.txt, w) file.write(text.replace(Left_RefAddr, FromLeft)) file.write(text.replace(Left_NonRefAddr, ToLeft)) file.write(text.replace(Right_RefAddr, FromRight)) file.write(text.replace(Right_NonRefAddr, ToRight)) file.close() Here's a perfect problem for a stream editor, like http://cheeseshop.python.org/pypi/SE/2.2%20beta. This is how it works: replacement_definitions = ''' Left_RefAddr=FromLeft Left_NonRefAddr=ToLeft Right_RefAddr=FromRight Right_NonRefAddr=ToRight ''' import SE Replacements = SE.SE (replacement_definitions) Replacements ('text.txt', 'new_text.txt') That's all! Or in place: ALLOW_IN_PLACE = 3 Replacements.set (file_handling_flag = ALLOW_IN_PLACE) Replacements ('text.txt') This should solve your task. An SE object takes strings too, which is required for line-by-line processing and is very useful for development or verification: print Replacements (replacement_definitions) # Use definitions as test data FromLeft=FromLeft ToLeft=ToLeft FromRight=FromRight ToRight=ToRight Checks out. All substitutions are made. Regards Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Attempting to parse free-form ANSI text.
Dennis Lee Bieber wrote: On Mon, 23 Oct 2006 20:34:20 +0100, Steve Holden [EMAIL PROTECTED] declaimed the following in comp.lang.python: Don't give up, attach it as a file! Which might be acceptable on a mailing list, but might be problematic on a text newsgroup... Though one attachment a year might not be noticed by those providers with strict binaries in binary groups only G The comment isn't lost on me. Much less as it runs in an open door. Funny thing is that I verified my settings by sending the message to myself and it looked fine. Then I sent it to the news group and it was messed up again. I will work some more on my setting. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: mean ans std dev of an array?
SpreadTooThin wrote: import array a = array.array('f', [1,2,3]) print a.mean() print a.std_dev() Is there a way to calculate the mean and standard deviation on array data? Do I need to import it into a Numeric Array to do this? I quickly fish this out of my functions toolbox. There's got to be faster functions in scipy, though. Frederic (Disclaimer: If you build an air liner or a ocean liner with this and the wings fall off at thirty thousand feet or it turns upside down in the middle of an ocean, respectively of course, I expect a bunch of contingency lawers lining up at my door wanting to sue you on my behalf.) def standard_deviation (values): Takes a sequence and returns mean, variance and standard deviation. Non-values (None) are skipped import math mean = _sum_values_squared = _sum_values = 0.0 l = len (values) i = 0 item_count = 0 while i l: value = values [i] if value != None: _sum_values += value _sum_values_squared += value * value item_count += 1 i += 1 if item_count 2: # having skipped all Nones return None, None, None mean = _sum_values / item_count variance = (_sum_values_squared - item_count * mean * mean) / (item_count - 1) if variance 0.0: variance = 0.0 # Rounding errors can cause minute negative values which would crash the sqrt standard_deviation = math.sqrt (variance) return mean, variance, standard_deviation -- http://mail.python.org/mailman/listinfo/python-list
Re: Attempting to parse free-form ANSI text.
Steve Holden wrote: Frederic Rentsch wrote: Frederic Rentsch wrote: Frederic Rentsch wrote: Paul McGuire wrote: Michael B. Trausch mike$#at^nospam!%trauschus wrote in message Sorry about the line wrap mess in the previous message. I try again with another setting: Frederic I give up! Don't give up, attach it as a file! regards Steve Thank you for the encourangement! Frederic The following code does everything Mike needs to do, except interact with wx. It is written to run standing alone. To incorporate it in Mike's class the functions would be methods and the globals would be instance attributes. Running it does this: chunk_1 = This is a test string containing some ANSI sequences. Sequence 1 Valid code, invalid numbers: \x1b[10;12mEnd of sequence 1 Sequence 2 Not an 'm'-code: \x1b[30;4;77hEnd of sequence 2 Sequence 3 Color setting code: \x1b[30;45mEnd of sequence 3 Sequence 4 Parameter setting code: \x1b[7mEnd of sequence 4 Sequence 5 Color setting code spanning calls: \x1b[3 chunk_2 = 7;42mEnd of sequence 5 Sequence 6 Invalid code: \x1b[End of sequence 6 Sequence 7 A valid code at the end: \x1b[9m init () process_text (chunk_1) process_text (chunk_2) print output This is a test string containing some ANSI sequences. Sequence 1 Valid code, invalid numbers: !!!Ignoring unknown number 10!!! !!!Ignoring unknown number 1!!! End of sequence 1 Sequence 2 Not an 'm'-code: End of sequence 2 Sequence 3 Color setting code: setting foreground BLACK setting background MAGENTA End of sequence 3 Sequence 4 Parameter setting code: Calling parameter setting function 7 End of sequence 4 Sequence 5 Color setting code spanning calls: setting foreground GREY setting background GREEN End of sequence 5 Sequence 6 Invalid code: nd of sequence 6 Sequence 7 A valid code at the end: Calling parameter setting function 9 # def init (): # This would have to be added to __init__ () import SE # SEL is less import overhead but doesn't have interactive development features (not needed in production versions) global output #- For testing global Pre_Processor, digits_re, Colors, truncated_escape_hold # global - instance attributes # Screening out invalid characters and all ansi escape sequences except those controlling color grit = '\n'.join (['(%d)=' % i for i in range (128,255)]) + ' (13)= ' # Makes 127 fixed expressions plus deletion of \r # Regular expression r'[\x80-\xff\r]' would work fine but is four times slower than 127 fixed expressions all_escapes = r'\x1b\[\d*(;\d*)*[A-Za-z]' color_escapes = r'\x1b\[\d*(;\d*)*m' Pre_Processor = SE.SE ('%s ~%s~= ~%s~==' % (grit, all_escapes, color_escapes)) # SEL.SEL for production # 'all_escapes' also matches what 'color_escapes' matches. With identical regular expression matches the last regex definition applies. # Isolating digits. digits_re = re.compile ('\d+') # Color numbers to color names Colors = SE.SE (''' 30=BLACK40=BLACK 31=RED 41=RED 32=GREEN42=GREEN 33=YELLOW 43=YELLOW 34=BLUE 44=BLUE 35=MAGENTA 45=MAGENTA 36=CYAN 46=CYAN 37=GREY 47=GREY 39=GREY 49=BLACK EAT ''') truncated_escape_hold = '' #- self.truncated_escape_hold output= '' #- For testing only # What follows replaces all others of Mike's methods in class AnsiTextCtrl(wx.TextCtrl) def process_text (text): global output #- For testing global truncated_escape_hold, digits_re, Pre_Processor, Colors purged_text = truncated_escape_hold + Pre_Processor (text) # Text is now clean except for color codes, which beginning with ESC ansi_controlled_sections = purged_text.split ('\x1b') # Each section starts with a color control, except the first one (leftmost split-off) if ansi_controlled_sections: #- self.AppendText(ansi_controlled_sections [0]) #- For real output += ansi_controlled_sections [0]#- For testing for section in ansi_controlled_sections [1:]: if section == '': continue try: escape_ansi_controlled_section, data = section.split ('m', 1) except ValueError: # Truncated escape truncated_escape_hold = '\x1b' + section # Restore ESC removed by split ('\x1b') else: escapes = escape_ansi_controlled_section.split (';') for escape in escapes: try: number = digits_re.search (escape).group () except AttributeError: output += ' !!!Invalid number %s!!! ' % escape#- For testing continue _set_wx (number) #- self.AppendText(data) #- For real output += data#- For testing def _set_wx (n): global output
Re: can't open word document after string replacements
Antoine De Groote wrote: Hi there, I have a word document containing pictures and text. This documents holds several 'ABCDEF' strings which serve as a placeholder for names. Now I want to replace these occurences with names in a list (members). I open both input and output file in binary mode and do the transformation. However, I can't open the resulting file, Word just telling that there was an error. Does anybody what I am doing wrong? Oh, and is this approach pythonic anyway? (I have a strong Java background.) Regards, antoine import os members = somelist os.chdir(somefolder) doc = file('ttt.doc', 'rb') docout = file('ttt1.doc', 'wb') counter = 0 for line in doc: while line.find('ABCDEF') -1: try: line = line.replace('ABCDEF', members[counter], 1) docout.write(line) counter += 1 except: docout.write(line.replace('ABCDEF', '', 1)) else: docout.write(line) doc.close() docout.close() DOC files contain housekeeping info which becomes inconsistent if you change text. Possibly you can exchange stuff of equal length but that wouldn't serve your purpose. RTF files let you do substitutions and they save a lot of space too. But I kind of doubt whether RTF files can contain pictures. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Attempting to parse free-form ANSI text.
Paul McGuire wrote: Michael B. Trausch mike$#at^nospam!%trauschus wrote in message news:[EMAIL PROTECTED] Alright... I am attempting to find a way to parse ANSI text from a telnet application. However, I am experiencing a bit of trouble. What I want to do is have all ANSI sequences _removed_ from the output, save for those that manage color codes or text presentation (in short, the ones that are ESC[#m (with additional #s separated by ; characters). The ones that are left, the ones that are the color codes, I want to act on, and remove from the text stream, and display the text. Here is a pyparsing-based scanner/converter, along with some test code at the end. It takes care of partial escape sequences, and strips any sequences of the form ESC[##;##;...alpha, unless the trailing alpha is 'm'. The pyparsing project wiki is at http://pyparsing.wikispaces.com. -- Paul from pyparsing import * snip test = \ This is a test string containing some ANSI sequences. Sequence 1: ~[10;12m Sequence 2: ~[3;4h Sequence 3: ~[4;5m Sequence 4; ~[m Sequence 5; ~[24HNo more escape sequences. ~[7.replace('~',chr(27)) leftOver = processInputString(test) Prints: This is a test string containing some ANSI sequences. Sequence 1: change color attributes to ['1012'] I doubt we should concatenate numbers. Sequence 2: Sequence 3: change color attributes to ['45'] Sequence 4; change color attributes to [''] Sequence 5; No more escape sequences. found partial escape sequence ['\x1b[7'], tack it on front of next Another one of Paul's elegant pyparsing solutions. To satisfy my own curiosity, I tried to see how SE stacked up and devoted more time than I really should to finding out. In the end I don't know if it was worth the effort, but having made it I might as well just throw it in. The following code does everything Mike needs to do, except interact with wx. It is written to run standing alone. To incorporate it in Mike's class the functions would be methods and the globals would be instance attributes. Running it does this: chunk_1 = This is a test string containing some ANSI sequences. Sequence 1 Valid code, invalid numbers: \x1b[10;12mEnd of sequence 1 Sequence 2 Not an 'm'-code: \x1b[30;4;77hEnd of sequence 2 Sequence 3 Color setting code: \x1b[30;45mEnd of sequence 3 Sequence 4 Parameter setting code: \x1b[7mEnd of sequence 4 Sequence 5 Color setting code spanning calls: \x1b[3 chunk_2 = 7;42mEnd of sequence 5 Sequence 6 Invalid code: \x1b[End of sequence 6 Sequence 7 A valid code at the end: \x1b[9m init () process_text (chunk_1) process_text (chunk_2) print output This is a test string containing some ANSI sequences. Sequence 1 Valid code, invalid numbers: ! Ignoring unknown number 10 ! ! Ignoring unknown number 12 ! End of sequence 1 Sequence 2 Not an 'm'-code: End of sequence 2 Sequence 3 Color setting code: setting foreground BLACK setting background MAGENTA End of sequence 3 Sequence 4 Parameter setting code: Calling parameter setting function 7 End of sequence 4 Sequence 5 Color setting code spanning calls: setting foreground GREY setting background GREEN End of sequence 5 Sequence 6 Invalid code: nd of sequence 6 Sequence 7 A valid code at the end: Calling parameter setting function 9 ### And here it goes: def init (): # To add to AnsiTextCtrl.__init__ () import SE # SEL is less import overhead but doesn't have interactive development features (not needed in production versions) global output #- For testing global Pre_Processor, digits_re, Colors, truncated_escape_hold # global - instance attributes # Screening out all ansi escape sequences except those controlling color grit = '\n'.join (['(%d)=' % i for i in range (128,255)]) + ' (13)= ' # Regular expression r'[\x80-\xff\r]' would work fine but is four times slower than 127 fixed definitions all_escapes = r'\x1b\[\d*(;\d*)*[A-Za-z]' color_escapes = r'\x1b\[\d*(;\d*)*m' Pre_Processor = SE.SE ('%s ~%s~= ~%s~==' % (grit, all_escapes, color_escapes)) # SEL.SEL for production # 'all_escapes' also matches what 'color_escapes' matches. With identical regular expression matches it is the last definitions that applies. Other than that, the order of definitions is irrelevant to precedence. # Isolating digits. digits_re = re.compile ('\d+') # Color numbers to color names Colors = SE.SE (''' 30=BLACK40=BLACK 31=RED 41=RED 32=GREEN42=GREEN 33=YELLOW 43=YELLOW 34=BLUE 44=BLUE 35=MAGENTA 45=MAGENTA 36=CYAN 46=CYAN 37=GREY 47=GREY 39=GREY 49=BLACK EAT ''') truncated_escape_hold = '' #- self.truncated_escape_hold output= '' #- For testing only # What follows replaces all others of Mike's methods def process_text (text): global output #-
Re: Attempting to parse free-form ANSI text.
Frederic Rentsch wrote: Paul McGuire wrote: Michael B. Trausch mike$#at^nospam!%trauschus wrote in message Sorry about the line wrap mess in the previous message. I try again with another setting: Frederic ## The following code does everything Mike needs to do, except interact with wx. It is written to run standing alone. To incorporate it in Mike's class the functions would be methods and the globals would be instance attributes. Running it does this: chunk_1 = This is a test string containing some ANSI sequences. Sequence 1 Valid code, invalid numbers: \x1b[10;12mEnd of sequence 1 Sequence 2 Not an 'm'-code: \x1b[30;4;77hEnd of sequence 2 Sequence 3 Color setting code: \x1b[30;45mEnd of sequence 3 Sequence 4 Parameter setting code: \x1b[7mEnd of sequence 4 Sequence 5 Color setting code spanning calls: \x1b[3 chunk_2 = 7;42mEnd of sequence 5 Sequence 6 Invalid code: \x1b[End of sequence 6 Sequence 7 A valid code at the end: \x1b[9m init () process_text (chunk_1) process_text (chunk_2) print output This is a test string containing some ANSI sequences. Sequence 1 Valid code, invalid numbers: !!!Ignoring unknown number 10!!! !!!Ignoring unknown number 1!!! End of sequence 1 Sequence 2 Not an 'm'-code: End of sequence 2 Sequence 3 Color setting code: setting foreground BLACK setting background MAGENTA End of sequence 3 Sequence 4 Parameter setting code: Calling parameter setting function 7 End of sequence 4 Sequence 5 Color setting code spanning calls: setting foreground GREY setting background GREEN End of sequence 5 Sequence 6 Invalid code: nd of sequence 6 Sequence 7 A valid code at the end: Calling parameter setting function 9 # def init (): # To add to AnsiTextCtrl.__init__ () import SE # SEL is less import overhead but doesn't have interactive development features (not needed in production versions) global output #- For testing global Pre_Processor, digits_re, Colors, truncated_escape_hold # global - instance attributes # Screening out all ansi escape sequences except those controlling color grit = '\n'.join (['(%d)=' % i for i in range (128,255)]) + ' (13)= ' # Makes 127 fixed expressions plus delete \r # Regular expression r'[\x80-\xff\r]' would work fine but is four times slower than 127 fixed expressions all_escapes = r'\x1b\[\d*(;\d*)*[A-Za-z]' color_escapes = r'\x1b\[\d*(;\d*)*m' Pre_Processor = SE.SE ('%s ~%s~= ~%s~==' % (grit, all_escapes, color_escapes)) # SEL.SEL for production # 'all_escapes' also matches what 'color_escapes' matches. With identical regular expression matches the last regex definitions applies. # Isolating digits. digits_re = re.compile ('\d+') # Color numbers to color names Colors = SE.SE (''' 30=BLACK40=BLACK 31=RED 41=RED 32=GREEN42=GREEN 33=YELLOW 43=YELLOW 34=BLUE 44=BLUE 35=MAGENTA 45=MAGENTA 36=CYAN 46=CYAN 37=GREY 47=GREY 39=GREY 49=BLACK EAT ''') truncated_escape_hold = '' #- self.truncated_escape_hold output= '' #- For testing only # What follows replaces all others of Mike's methods def process_text (text): global output #- For testing global truncated_escape_hold, digits_re, Pre_Processor, Colors purged_text = truncated_escape_hold + Pre_Processor (text) # Text is now clean except for color codes beginning with ESC ansi_controlled_sections = purged_text.split ('\x1b') # Each ansi_controlled_section starts with a color control, except the first one (leftmost split-off) if ansi_controlled_sections: #- self.AppendText(ansi_controlled_sections [0]) #- For real output += ansi_controlled_sections [0] #- For testing #- For testing for section in ansi_controlled_sections [1:]: if section == '': continue try: escape_ansi_controlled_section, data = section.split ('m', 1) except ValueError: # Truncated escape truncated_escape_hold = '\x1b' + section # Restore ESC removed by split ('\x1b') else: escapes = escape_ansi_controlled_section.split (';') for escape in escapes: try: number = digits_re.search (escape).group () except AttributeError: output += ' !!!Invalid number %s!!! ' % escape #- For testing continue _set_wx (number) #- self.AppendText(data) #- For real output += data#- For testing def _set_wx (n): global output # For testing only global Colors int_n = int (n) if 0 = int_n = 9: #- self._number_to_method (n)() #- For real output += ' Calling parameter setting function %s ' % n #- For testing return color = Colors (n) if color: if 30 = int_n 50
Re: Attempting to parse free-form ANSI text.
Frederic Rentsch wrote: Frederic Rentsch wrote: Paul McGuire wrote: Michael B. Trausch mike$#at^nospam!%trauschus wrote in message Sorry about the line wrap mess in the previous message. I try again with another setting: Frederic I give up! -- http://mail.python.org/mailman/listinfo/python-list
Re: Attempting to parse free-form ANSI text.
Michael B. Trausch wrote: Alright... I am attempting to find a way to parse ANSI text from a telnet application. However, I am experiencing a bit of trouble. What I want to do is have all ANSI sequences _removed_ from the output, save for those that manage color codes or text presentation (in short, the ones that are ESC[#m (with additional #s separated by ; characters). The ones that are left, the ones that are the color codes, I want to act on, and remove from the text stream, and display the text. I am using wxPython's TextCtrl as output, so when I get an ANSI color control sequence, I want to basically turn it into a call to wxWidgets' TextCtrl.SetDefaultStyle method for the control, adding the appropriate color/brightness/italic/bold/etc. settings to the TextCtrl until the next ANSI code comes in to alter it. It would *seem* easy, but I cannot seem to wrap my mind around the idea. :-/ I have a source tarball up at http://fd0man.theunixplace.com/Tmud.tar which contains the code in question. In short, the information is coming in over a TCP/IP socket that is traditionally connected to with a telnet client, so things can be broken mid-line (or even mid-control sequence). If anyone has any ideas as to what I am doing, expecting, or assuming that is wrong, I would be delighted to hear it. The code that is not behaving as I would expect it to is in src/AnsiTextCtrl.py, but I have included the entire project as it stands for completeness. Any help would be appreciated! Thanks! -- Mike *I have no experience with reading from TCP/IP. But looking at your program with a candid mind I'd say that it is written to process a chunk of data in memory. If, as you say, the chunks you get from TCP/IP may start and end anywhere and, presumably you pass each chunk through AppendText, then you have a synchronization problem, as each call resets your escape flag, even if the new chunk starts in the middle of an escape sequence. Perhaps you should cut off incomplete escapes at the end and prepend them to the next chunk. And: if(len(buffer) 0): wx.TextCtrl.AppendText(self, buffer) Are you sure text goes into the same place as the controls? if(len(AnsiBuffer) 0): wx.TextCtrl.AppendText(self, AnsiBuffer) You say you want to strip the control sequences Frederic * -- http://mail.python.org/mailman/listinfo/python-list
Re: File read-write mode: problem appending after reading
Tim Peters wrote: [Frederic Rentsch] Thanks a lot for your input. I seemed to notice that everything works fine without setting the cursor as long as it stops before the end of the file. Is that also a coincidence that may not work? if you want to read following a write, or write following a read, on the same stream, you must perform a file-positioning operation (typically a seek) between them I appreciate the clarification. Thanks! -- http://mail.python.org/mailman/listinfo/python-list
Re: Ok. This IS homework ...
spawn wrote: but I've been struggling with this for far too long and I'm about to start beating my head against the wall. My assignment seemed simple: create a program that will cacluate the running total of user inputs until it hits 100. At 100 it should stop. That's not the problem, in fact, that part works. It's the adding that isn't working. How can my program add 2 + 7 and come up with 14? I'm posting my code (so that you may all laugh). If ANYONE has any ideas on what I'm doing wrong, I'd appreciate. --- running = True goal = 100 # subtotal = 0 # running_total = subtotal + guess while running: guess = int(raw_input('Enter an integer that I can use to add : ')) subtotal = guess while running: guess = int(raw_input('I\'ll need another number : ')) running_total = guess + subtotal print running_total if running_total == goal: print 'Congratulations! You\'re done.' elif running_total goal: print 'That\'s a good number, but too high. Try again.' print 'Done' -- I tried adding an additional while statement to capture the second number, but it didn't seem to solve my problem. Help! Dear anonymous student, Once upon a time programmers did things like this: BEGIN | --|- | | | | catch input| | | | | input type valid? - prompt for correct input --| | + | |input too large? + --- prompt for new input -- | - | add to running total | | | status report | | -- - running total = max? + report done | END It was called a flow chart. Flow charts could be translated directly into machine code written in assembly languages which had labels, tests and jumps as the only flow-control constructs. When structured programming introduced for and while loops they internalized labeling and jumping. That was a great convenience. Flow-charting became rather obsolete because the one-to-one correspondence between flow chart and code was largely lost. I still find flow charting useful for conceptualizing a system of logical states too complex for my intuition. Everybody's intuition has a limit. Your homework solution shows that the assignment exceeds yours. So my suggestion is that you use the flow chart, like this: def homework (): # Local functions. (I won't do those for you.) def explain_rules (): def check_type (r): def explain_type (): def check_size (r): def explain_max_size (): def report_status (rt): def report_done (): # Main function GOAL = 100 #BEGIN MAX_INPUT = 20 # | running_total = 0 # | # | explain_rules () # | # | while 1: # --|- # | | | response = raw_input ('Enter a number ') # | catch input| # | | | if check_type (response) == False: # | input type valid? - prompt for correct input --| explain_type () # | + | continue# | | | # | | | if check_size (response) == False: # |input too large? + --- prompt for new input -- explain_max_size () # | - continue# | | # | | running_total += int (response)# | add to running total report_status (running_total) # |
Re: Ok. This IS homework ...
Nick Craig-Wood wrote: Frederic Rentsch [EMAIL PROTECTED] wrote: It was called a flow chart. Flow charts could be translated directly into machine code written in assembly languages which had labels, tests and jumps as the only flow-control constructs. When structured programming introduced for and while loops they internalized labeling and jumping. That was a great convenience. Flow-charting became rather obsolete because the one-to-one correspondence between flow chart and code was largely lost. The trouble with flow charts is that they aren't appropriate maps for the modern computing language territory. Yes. That's why they aren't used anymore. I was born and bred on flow charts and I admit they were useful back in the days when I wrote 1000s of lines of assembler code a week. Now-a-days a much better map for the the territory is pseudo-code. Python is pretty much executable pseudo-code anway Yes. But it's the executable pseudo code our friend has problems with. So your very pertinent observation doesn't help him. My suggestion to use a flow chart was on the impression that he didn't have a clear conception of the solution's logic and that the flow chart was a simple means to acquire that clear conception. I like flow charts because they exhaustively map states and transitions exactly the way they connect---solution imaging as it were. If they can help intelligence map a territory it is no issue if they don't map it themselves very well. -- http://mail.python.org/mailman/listinfo/python-list
Re: Insert characters into string based on re ?
Frederic Rentsch wrote: Matt wrote: I am attempting to reformat a string, inserting newlines before certain phrases. For example, in formatting SQL, I want to start a new line at each JOIN condition. Noting that strings are immutable, I thought it best to spllit the string at the key points, then join with '\n'. Regexps can seem the best way to identify the points in the string ('LEFT.*JOIN' to cover 'LEFT OUTER JOIN' and 'LEFT JOIN'), since I need to identify multiple locationg in the string. However, the re.split method returns the list without the split phrases, and re.findall does not seem useful for this operation. Suggestions? Matt, You may want to try this solution: import SE ... snip http://cheeseshop.python.org/pypi?:action=displayname=SEversion=2.3 For reasons unknown, the new download for SE is on the old page: http://cheeseshop.python.org/pypi/SE/2.2%20beta. Frederic -- -- http://mail.python.org/mailman/listinfo/python-list
Re: File read-write mode: problem appending after reading
Tim, Thanks a lot for your input. I seemed to notice that everything works fine without setting the cursor as long as it stops before the end of the file. Is that also a coincidence that may not work? Frederic Tim Peters wrote: [Frederic Rentsch] Working with read and write operations on a file I stumbled on a complication when writes fail following a read to the end. f = file ('T:/z', 'r+b') f.write ('abcdefg') f.tell () 30L f.seek (0) f.read () 'abcdefg' f.flush () # Calling or not makes no difference f.write ('abcdefg') Nothing is defined about what happens at this point, and this is inherited from C. In standard C, if you want to read following a write, or write following a read, on the same stream, you must perform a file-positioning operation (typically a seek) between them. Traceback (most recent call last): File pyshell#62, line 1, in -toplevel- f.write ('abcdefg') IOError: (0, 'Error') That's one possible result. Since nothing is defined, any other outcome is also a possible result ;-) Flushing doesn't help. Right, and because flush() is not a file-positioning operation. I found two work arounds: f.read () 'abcdefg' f.read () # Workaround 1: A second read (returning an empty string) '' f.write ('abcdefg') (No error) Purely an accident; may or may not work the next time you try it, or on another platform; etc. f.read () 'abcdefg' f.seek (f.tell ()) # Workaround 2: Setting the cursor (to where it is!) That's a correct approach. f.seek(0, 1) (seek 0 bytes from the current position) is a little easier to spell. f.write ('abcdefg') (No error) I found no problem with writing into the file. So it looks like it has to do with the cursor which a read puts past the end, unless it is past the end, in which case it goes back to the end. Is there a less kludgy alternative to fseek (ftell ())? As above, you need to seek when switching from reading to writing, or from writing to reading. -- http://mail.python.org/mailman/listinfo/python-list
Re: Insert characters into string based on re ?
Matt wrote: I am attempting to reformat a string, inserting newlines before certain phrases. For example, in formatting SQL, I want to start a new line at each JOIN condition. Noting that strings are immutable, I thought it best to spllit the string at the key points, then join with '\n'. Regexps can seem the best way to identify the points in the string ('LEFT.*JOIN' to cover 'LEFT OUTER JOIN' and 'LEFT JOIN'), since I need to identify multiple locationg in the string. However, the re.split method returns the list without the split phrases, and re.findall does not seem useful for this operation. Suggestions? Matt, You may want to try this solution: import SE Formatter = SE.SE (' ~(?i)(left|inner|right|outer).*join~=\n= ') # Details explained below the dotted line print Formatter ('select id, people.* from ids left outer join people where ...\nSELECT name, job from people INNER JOIN jobs WHERE ...;\n') select id, people.* from ids left outer join people where ... SELECT name, job from people INNER JOIN jobs where ...; You may add other substitutions as required one by one, interactively tweaking each one until it does what it is supposed to do: Formatter = SE.SE (''' ~(?i)(left|inner|right|outer).*join~=\n = # Add an indentation where=\n where WHERE=\n WHERE # Add a newline also before 'where' ;\n=;\n\n # Add an extra line feed \n=;\n\n# And add any missing semicolon # etc. ''') print Formatter ('select id, people.* from ids left outer join people where ...\nSELECT name, job from people INNER JOIN jobs WHERE ...;\n') select id, people.* from ids left outer join people where ...; SELECT name, job from people INNER JOIN jobs WHERE ...; http://cheeseshop.python.org/pypi?:action=displayname=SEversion=2.3 Frederic -- The anatomy of a replacement definition Formatter = SE.SE (' ~(?i)(left|inner|right|outer).*join~=\n= ') target=substitute (first '=') Formatter = SE.SE (' ~(?i)(left|inner|right|outer).*join~=\n= ') = (each following '=' stands for matched target) Formatter = SE.SE (' ~(?i)(left|inner|right|outer).*join~=\n= ') ~ ~ (contain regular expression) Formatter = SE.SE (' ~(?i)(left|inner|right|outer).*join~=\n= ') (contain definition containing white space) -- http://mail.python.org/mailman/listinfo/python-list
File read-write mode: problem appending after reading
Hi all, Working with read and write operations on a file I stumbled on a complication when writes fail following a read to the end. f = file ('T:/z', 'r+b') f.write ('abcdefg') f.tell () 30L f.seek (0) f.read () 'abcdefg' f.flush () # Calling or not makes no difference f.write ('abcdefg') Traceback (most recent call last): File pyshell#62, line 1, in -toplevel- f.write ('abcdefg') IOError: (0, 'Error') Flushing doesn't help. I found two work arounds: f.read () 'abcdefg' f.read () # Workaround 1: A second read (returning an empty string) '' f.write ('abcdefg') (No error) f.read () 'abcdefg' f.seek (f.tell ()) # Workaround 2: Setting the cursor (to where it is!) f.write ('abcdefg') (No error) I found no problem with writing into the file. So it looks like it has to do with the cursor which a read puts past the end, unless it is past the end, in which case it goes back to the end. Is there a less kludgy alternative to fseek (ftell ())? Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Operator += works once, fails if called again
John Machin wrote: Frederic Rentsch wrote: Hi all, I have a class Time_Series derived from list. It lists days and contains a dictionary of various Lists also derived from list which contain values related to said days. (e.g. Stock quotes, volumes traded, etc.) I defined an operator += which works just fine, but only once. If I repeat the operation, it fails and leaves me utterly mystified and crushed. Craving to be uncrushed by a superior intelligence. Frederic --- A test: [perfection snipped] Perfect! TS1 += TS2# Second call Traceback (most recent call last): File pyshell#311, line 1, in -toplevel- TS += TS2 File c:\i\sony\fre\src\python\TIME_SERIES_7.py, line 1314, in __iadd__ return self.__add__ (other) File c:\i\sony\fre\src\python\TIME_SERIES_7.py, line 1273, in __add__ Sum = copy.deepcopy (self) File C:\PYTHON24\lib\copy.py, line 188, in deepcopy y = _reconstruct(x, rv, 1, memo) File C:\PYTHON24\lib\copy.py, line 335, in _reconstruct state = deepcopy(state, memo) File C:\PYTHON24\lib\copy.py, line 161, in deepcopy y = copier(x, memo) File C:\PYTHON24\lib\copy.py, line 252, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File C:\PYTHON24\lib\copy.py, line 161, in deepcopy y = copier(x, memo) File C:\PYTHON24\lib\copy.py, line 252, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File C:\PYTHON24\lib\copy.py, line 188, in deepcopy y = _reconstruct(x, rv, 1, memo) File C:\PYTHON24\lib\copy.py, line 335, in _reconstruct state = deepcopy(state, memo) File C:\PYTHON24\lib\copy.py, line 161, in deepcopy y = copier(x, memo) File C:\PYTHON24\lib\copy.py, line 252, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File C:\PYTHON24\lib\copy.py, line 188, in deepcopy y = _reconstruct(x, rv, 1, memo) File C:\PYTHON24\lib\copy.py, line 320, in _reconstruct y = callable(*args) File C:\PYTHON24\lib\copy_reg.py, line 92, in __newobj__ Oho! What's it doing there, in copy_reg.py? Something has stashed away a reference to copy_reg.__newobj__, and the stasher is *not* the copy module return cls.__new__(cls, *args) TypeError: instancemethod expected at least 2 arguments, got 0 From a quick browse through the code for copy.py and copy_reg.py [Isn't open source a wonderful thing?], I'm guessing: (1) The cls is *your* class. You can confirm that with a debugger (or by hacking in a print statement!). (2) You may need to read this in the copy docs: Classes can use the same interfaces to control copying that they use to control pickling. See the description of module pickle for information on these methods. The copy module does not use the copy_reg registration module. (3) You may need to read this in the pickle docs: New-style types can provide a __getnewargs__() method that is used for protocol 2. Implementing this method is needed if the type establishes some internal invariants when the instance is created, or if the memory allocation is affected by the values passed to the __new__() method for the type (as it is for tuples and strings). Instances of a new-style type C are created using obj = C.__new__(C, *args) where args is the result of calling __getnewargs__() on the original object; if there is no __getnewargs__(), an empty tuple is assumed. (4) You may need to debug your pickling/unpickling before you debug your deepcopying. (5) Look at function _copy_inst at line 134 in copy.py -- work out what it will do with your class instance, depending on what __magic__ method(s) you have implemented. Hope some of this helps, John John, Thank you very much for your suggestions. I followed them one by one and in the end found the cause of the problem to be a circular reference. Some species of contained Lists need a reference to the containing Time_Series and that circular reference trips up deepcopy. Supposedly I can define my own __deepcopy__, but didn't understand whose method it is supposed to be. Time_Series.__deepcopy__ () doesn't make sens, nor does it work. Time_Series should be the argument of the method not the owner. Anyway, I managed without deepcopy making a new instance and loading it as I would, if it were the first one. Thanks again Frederic -- http://mail.python.org/mailman/listinfo/python-list
Operator += works once, fails if called again
Hi all, I have a class Time_Series derived from list. It lists days and contains a dictionary of various Lists also derived from list which contain values related to said days. (e.g. Stock quotes, volumes traded, etc.) I defined an operator += which works just fine, but only once. If I repeat the operation, it fails and leaves me utterly mystified and crushed. Craving to be uncrushed by a superior intelligence. Frederic --- A test: TS1 = TIME_SERIES_7.Time_Series (range (10), 'TS1') # Some days L1 = LIST_7.Floats ((22,44,323,55,344,55,66,77,-1,0), 'Numbers') # Some List with values TS1.add_List (L1) TS2 = TIME_SERIES_7.Time_Series ((3,4,5,7,8), 'TS2') # Other days (subset) L2 = LIST_7.Floats ((7,-2,-5,0,2), 'Numbers') # Another List with values TS2.add_list (L2) TS1 += TS2# First call TS1.write () TS1 | Date | Numbers | 0.00 | 1900.00.00 | 22.00 | 1.00 | 1900.01.01 | 44.00 | 2.00 | 1900.01.02 | 323.00 | 3.00 | 1900.01.03 | 62.00 | 4.00 | 1900.01.04 | 342.00 | 5.00 | 1900.01.05 | 50.00 | 6.00 | 1900.01.06 | 63.00 | 7.00 | 1900.01.07 | 77.00 | 8.00 | 1900.01.08 | -1.00 | 9.00 | 1900.01.09 |0.00 | Perfect! TS1 += TS2# Second call Traceback (most recent call last): File pyshell#311, line 1, in -toplevel- TS += TS2 File c:\i\sony\fre\src\python\TIME_SERIES_7.py, line 1314, in __iadd__ return self.__add__ (other) File c:\i\sony\fre\src\python\TIME_SERIES_7.py, line 1273, in __add__ Sum = copy.deepcopy (self) File C:\PYTHON24\lib\copy.py, line 188, in deepcopy y = _reconstruct(x, rv, 1, memo) File C:\PYTHON24\lib\copy.py, line 335, in _reconstruct state = deepcopy(state, memo) File C:\PYTHON24\lib\copy.py, line 161, in deepcopy y = copier(x, memo) File C:\PYTHON24\lib\copy.py, line 252, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File C:\PYTHON24\lib\copy.py, line 161, in deepcopy y = copier(x, memo) File C:\PYTHON24\lib\copy.py, line 252, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File C:\PYTHON24\lib\copy.py, line 188, in deepcopy y = _reconstruct(x, rv, 1, memo) File C:\PYTHON24\lib\copy.py, line 335, in _reconstruct state = deepcopy(state, memo) File C:\PYTHON24\lib\copy.py, line 161, in deepcopy y = copier(x, memo) File C:\PYTHON24\lib\copy.py, line 252, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File C:\PYTHON24\lib\copy.py, line 188, in deepcopy y = _reconstruct(x, rv, 1, memo) File C:\PYTHON24\lib\copy.py, line 320, in _reconstruct y = callable(*args) File C:\PYTHON24\lib\copy_reg.py, line 92, in __newobj__ return cls.__new__(cls, *args) TypeError: instancemethod expected at least 2 arguments, got 0 It seems to crash on the second call to deepcopy. Why? The type of the deepcopied object is still 'Time_Series'. Here's Time_Series.__add__ () but I don't think there's anything wrong with that. def __add__ (self, other): if self [0] = other [0]: # One or the other ... Sum = copy.deepcopy (self) Summand = copy.deepcopy (other) else: # depending on which starts earlier Sum = copy.deepcopy (other) Summand = copy.deepcopy (self) if Sum [0] != Summand [0]: Summand.insert (0, Sum [0]) for list_name in Summand.Lists: Summand.Lists [list_name].insert (0, None) if Sum [-1] Summand [-1]: Sum.append (Summand [-1]) elif Sum [-1] Summand [-1]: Summand.append (Sum [-1]) Sum.make_continuous () # Fills in missing days and values Summand.make_continuous () for list_name in Summand.Lists: if Sum.Lists.has_key (list_name): Sum.Lists [list_name] += Summand.Lists [list_name] # List operators work fine return Sum --- -- http://mail.python.org/mailman/listinfo/python-list
Re: Escapeism
Kay Schluehr wrote: Sybren Stuvel wrote: Kay Schluehr enlightened us with: Usually I struggle a short while with \ and either succeed or give up. Today I'm in a different mood and don't give up. So here is my question: You have an unknown character string c such as '\n' , '\a' , '\7' etc. How do you echo them using print? print_str( c ) prints representation '\a' to stdout for c = '\a' print_str( c ) prints representation '\n' for c = '\n' ... It is required that not a beep or a linebreak shall be printed. try print repr(c). This yields the hexadecimal representation of the ASCII character and does not simply echo the keystrokes '\' and 'a' for '\a' ignoring the escape semantics. One way to achieve this naturally is by prefixing '\a' with r where r'\a' indicates a raw string. But unfortunately rawrification applies only to string literals and not to string objects ( such as c ). I consider creating a table consisting of pairs {'\0': r'\0','\1': r'\1',...} i.e. a handcrafted mapping but maybe I've overlooked some simple function or trick that does the same for me. Kay Kay, This is perhaps yet another case for SE? I don't really know, because I don't quite get what you're after. See for yourself: import SE Printabilizer = SE.SE ( ''' (1)=\\1 # All 256 octets can be written as parenthesized ascii (2)=\\2 \a=\\a # (7)=\\a \n=\\n # or (10)=\\n or (10)=LF or whatever \r=\\r # (13)=CR \f=\\f \v=\\v # Add whatever other ones you like #and translate them to anything you like. ''') print Printabilizer ('abd\aefg\r\nhijk\vlmnop\1\2.') abd\aefg\r\nhijk\vlmno\1\2. If you think this may help, you'll find SE here: http://cheeseshop.python.org/pypi/SE/2.2%20beta Regards Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: Can string formatting be used to convert an integer to its binary form ?
[EMAIL PROTECTED] wrote: Frederic Rentsch: Good idea, but shorter with - SE.SE ('se_definition_files/int_to_binary.se') ('%X' % 987654321) '0011101011000110100010110001' Note that your version keeps the leading zeros. Have you tested the relative speeds too? (I'll probably have to learn to use SE.) Bye, bearophile If you say speed, I presume you mean speed of execution. No I have not tested that. I know it can't be fast on a test bench. After all, SE is written in Python. I did a first version fifteen years ago in C, am still using it today on occasion and it runs much, much faster than this Python SE. This SE here could be done in C if it passes the test of acceptance. Professionals need to measure execution speed as a part of documenting their products. I am not a professional and so I am free to define my own scale of grades: A (fast enough) and F (not fast enough). I have yet to encounter a situation where SE gets an F. But that says less about SE than about my better knowledge which prevents me from using SE to, say, change colors in a 50 Mb bitmap. Obviously, fast enough and not fast enough pertains not to code per se, but to code in a specific situation. So, as the saying goes: the proof of the pudding ... Another kind of speed is production speed. I do believe that SE rather excels on that side. I also believe that the two kinds of speed are economically related by the return-on-investment principle. The third kind of speed is learning speed. SE is so simple that it has no technical learning curve to speak of. It's versatility comes from a wealth of application techniques that invite exploration, invention even. Take leading zeroes: Leading zeroes can be stripped in a second pass if they are made recognizable in the first pass by some leading mark that is not a zero or a one. ([^01]; I use @ in the following example). To purists this may seem hackish. So it is! And what's wrong with that if it leads to simpler solutions? Hex_To_Binary = SE.SE ('0= 1=0001 2=0010 3=0011 4=0100 5=0101 6=0110 7=0111 8=1000 9=1001 A=1010 a=1010 B=1011 b=1011 C=1100 c=1100 D=1101 d=1101 E=1110 e=1110 F= f= | ~[^01]0*~=') Hex_To_Binary.set (keep_chain = 1) Hex_To_Binary ('@%x' % 1234567890) '100100110010110001011010010' Hex_To_Binary.show () ... snip ... Data Chain -- @499602d2 0 @0100100110010110001011010010 1 100100110010110001011010010 -- Frederic (The previously posted example Int_To_Binary = SE.SE (SE.SE ( ... was a typo, or course. One (SE.SE does it. Sorry about that.) -- http://mail.python.org/mailman/listinfo/python-list
Re: Can string formatting be used to convert an integer to its binary form ?
[EMAIL PROTECTED] wrote: Mirco Wahab: But where is the %b in Python? Python doesn't have that. You can convert the number to a hex, and then map the hex digitds to binary strings using a dictionary, like this: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440528 Bye, bearophile Good idea, but shorter with - http://cheeseshop.python.org/pypi/SE/2.2%20beta import SE Int_To_Binary = SE.SE (SE.SE ('0= 1=0001 2=0010 3=0011 4=0100 5=0101 6=0110 7=0111 8=1000 9=1001 A=1010 a=1010 B=1011 b=1011 C=1100 c=1100 D=1101 d=1101 E=1110 e=1110 F= f=') Int_To_Binary ('%x' % 1234567890') '0100100110010110001011010010' Int_To_Binary.save ('se_definition_files/int_to_binary.se') SE.SE ('se_definition_files/int_to_binary.se') ('%X' % 987654321) '0011101011000110100010110001' Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: I need some help with a regexp please
Dennis Lee Bieber wrote: On 25 Sep 2006 10:25:01 -0700, codefire [EMAIL PROTECTED] declaimed the following in comp.lang.python: Yes, I didn't make it clear in my original post - the purpose of the code was to learn something about regexps (I only started coding Python last week). In terms of learning a little more the example was successful. However, creating a full email validator is way beyond me - the rules are far too complex!! :) I've been doing small things in Python for over a decade now (starting with the Amiga port)... I still don't touch regular expressions... They may be fast, but to me they are just as much line noise as PERL... I can usually code a partial parser faster than try to figure out an RE. If I may add another thought along the same line: regular expressions seem to tend towards an art form, or an intellectual game. Many discussions revolving around regular expressions convey the impression that the challenge being pursued is finding a magic formula much more than solving a problem. In addition there seems to exist some code of honor which dictates that the magic formula must consist of one single expression that does it all. I suspect that the complexity of one single expression grows somehow exponentially with the number of functionalities it has to perform and at some point enters a gray zone of impending conceptual intractability where the quest for the magic formula becomes particularly fascinating. I also suspect that some problems are impossible to solve with a single expression and that no test of intractability exists other than giving up after so many hours of trying. With reference to the OP's question, what speaks against passing his texts through several simple expressions in succession? Speed of execution? Hardly. The speed penalty would not be perceptible. Conversely, in favor of multiple expressions speaks that they can be kept simple and that the performance of the entire set can be incrementally improved by adding another simple expression whenever an unexpected contingency occurs, as they may occur at any time with informal systems. One may not win a coding contest this way, but saving time isn't bad either, or is even better. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: newbe's re question
[EMAIL PROTECTED] wrote: Frederic Rentsch wrote: [EMAIL PROTECTED] wrote: These are csound files. Csound recently added python as a scripting language and is allowing also allowing csound calls from outside of csound. The nice thing about csound is that instead of worrying about virus and large files it is an interpiter and all the files look somewhat like html. 4,000 virus free instruments for $20 is available at http://www.csounds.com and the csound programming book is also available. The downside is that csound is can be realy ugly looking (that is what I am trying to change) and it lets you write ugly looking song code that is almost unreadable at times (would look nice in a grid) snip snip snip snip snip . I was hoping to add and remove instruments.. although the other should go into my example file because it will come in handy at some point. It would also be cool to get a list of instruments along with any comment line if there is one into a grid but that is two different functions. http://www.dexrow.com Eric, Below the dotted line there are two functions. csound_filter () extracts and formats instrument blocks from csound files and writes the output to another file. (If called without an output file name, the output displays on the screen). The second function, make_instrument_dictionaries (), takes the file generated by the first function and makes two dictionaries. One of them lists instrument ids keyed on instrument description, the other one does it the other way around, listing descriptions by instrument id. Instrument ids are file name plus instrument number. You cannot depend on this system to function reliably, because it extracts information from comments. I took my data from ems.music.utexas.edu/program/mus329j/CSPrimer.pdf the author of which happens to lead his instrument blocks with a header made up of comment lines, the first of which characterizes the block. That first line I use to make the dictionaries. If your data doesn't follow this practice, then you may not get meaningful dictionaries and are in for some hacking. In any case, this doesn't look like a job that can be fully automated. But if you can build your data base with a manageable amount of manual work you should be okay. The SE filter likewise works depending on formal consistency with my sample. If it fails, you may have to either tweak it or move up to a parser. I'll be glad to provide further assistance to the best of my knowledge. But you will have to make an effort to express yourself intelligibly. As a matter of fact the hardest part of proposing solutions to your problem is guessing what your problem is. I suggest you do this: before you post, show the message to a good friend and edit it until he understands it. Regards Frederic . def csound_filter (csound_file_name, name_of_formatted_instrument_blocks_file = sys.stdout): This function filters and formats instrument blocks out of a csound file. csound_formatter (csound_file_name, name_of_formatted_instrument_blocks_file) csound_formatter (csound_file_name) # Single argument: screen output import SE Instruments_Filter = SE.SE ('EAT ~;.*~==(10) ~instr(.|\n)*?endin~==(10)(10)') INDENT = 10 CODE_LENGTH = 50 def format (): for l in instruments_file: line = l.strip () if line == '': out_file.write ('\n') else: if line [0] == ';': # Comment line out_file.write ('%s\n' % line) else: code = comment = '' if line [-1] == ':': # Label out_file.write ('%s\n' % line) else: if ';' in line: code, comment = line.split (';') out_file.write ('%*s%-*s;%s\n' % (INDENT, '', CODE_LENGTH, code, comment)) else: out_file.write ('%*s%s\n' % (INDENT, '', line)) instruments_file_name = Instruments_Filter (csound_file_name) instruments_file = file (instruments_file_name, 'w+a') if name_of_formatted_instrument_blocks_file != sys.stdout: out_file = file (name_of_formatted_instrument_blocks_file, 'wa') owns_out_file = True else: out_file = name_of_formatted_instrument_blocks_file owns_out_file = False format () if owns_out_file: out_file.close () def make_instrument_dictionaries (name_of_formatted_instrument_blocks_file): This function takes a file made by the previous function and generates two dictionaries. One records instrument ids by description. The other one instrument descriptions by id. Instrument ids are made up of file name and instrument number. If these two
Re: newbe's re question
[EMAIL PROTECTED] wrote: These are csound files. Csound recently added python as a scripting language and is allowing also allowing csound calls from outside of csound. The nice thing about csound is that instead of worrying about virus and large files it is an interpiter and all the files look somewhat like html. 4,000 virus free instruments for $20 is available at http://www.csounds.com and the csound programming book is also available. The downside is that csound is can be realy ugly looking (that is what I am trying to change) and it lets you write ugly looking song code that is almost unreadable at times (would look nice in a grid) http://www.msn.com .. Frederic Rentsch wrote: [EMAIL PROTECTED] wrote: Frederic Rentsch wrote: [EMAIL PROTECTED] wrote: Frederic Rentsch wrote: [EMAIL PROTECTED] wrote: All I am after realy is to change this reline = re.line.split('instr', '/d$') into something that grabs any line with instr in it take all the numbers and then grab any comment that may or may not be at the end of the line starting with ; until the end of the line including white spaces.. this is a corrected version from http://python-forum.org/py/viewtopic.php?t=1703 thanks in advance the hole routine is down below.. [code] def extractCsdInstrument (input_File_Name, output_File_Name, instr_number): takes an .csd input file and grabs instr_number instrument and creates output_File_Name f = open (input_File_Name , 'r')#opens file passed in to read f2 = open (output_File_Name, 'w') #opens file passed in to write instr_yes = 'false' #set flag to false for line in f: #for through all the lines if instr in line: #look for instr in the file if instr_yes == 'true':#check to see if this ends the instr block break#exit the block reline = re.line.split('instr', '/d$') #error probily split instr and /d (decimal number into parts) $ for end of line number = int(reline[1]) #convert to a number maybe not important if number == instr_number:#check to see if it is the instr passed to function instr_yes = true: #change flag to true because this is the instr we want if instr_yes = true:#start of code to copy to another file f2.write(f.line) #write line to output file f.close #close input file f2.close [/code] Eric, From your problem description and your code it is unclear what exactly it is you want. The task appears to be rather simple, though, and if you don't get much useful help I'd say it is because you don't explain it very well. I believe we've been through this before and your input data is like this data = ''' CsoundSynthesizer; ; test.csd - a Csound structured data file CsOptions -W -d -o tone.wav /CsOptions CsVersion;optional section Before 4.10 ;these two statements check for After 4.08 ; Csound version 4.09 /CsVersion CsInstruments ; originally tone.orc sr = 44100 kr = 4410 ksmps = 10 nchnls = 1 instr 1 a1 oscil p4, p5, 1 ; simple oscillator out a1 endin /CsInstruments CsScore ; originally tone.sco f1 0 8192 10 1 i1 0 1 2 1000 ;play one second of one kHz tone e /CsScore /CsoundSynthesizer Question 1: Is this your input? if yes: Question 1.1: What do you want to extract from it? In what format? if no: Question 1.1: What is your input? Question 1.2: What do you want to extract from it? In what format? Question 2: Do you need to generate output file names from the data? (One file per instrument?) if yes: Question 2.1: What do you want to make your file name from? (Instrument number?) Regards Frederic I want to pass the file name to the subroutine and return a comment string if it is there maybe it should be simplier. I probily should have the option of grabbing the comment in other related routines. I am pretty ambitious with the main program. I did notice some code in tcl that would be usefull to the app If I compile it.. I am probily not ready for that though.. http://www.dexrow.com Eric, I'm beginning to enjoy this. I'm sure we'll sort this out in no time if we proceed methodically. Imagine you are a teacher and I am your student. This is a quiz. I have to take it and you need to explain to me the problem you want me to solve. If you don't
Re: Replacing line in a text file
CSUIDL PROGRAMMEr wrote: Folks I am trying to read a file This file has a line containing string 'disable = yes' I want to change this line to 'disable = no' The concern here is that , i plan to take into account the white spaces also. I tried copying all file int list and then tried to manipulate that list But the search is not working Any answer thanks s = '''Folks! I am trying to read a file This file has a line containing string 'disable = yes' I want to change this line to 'disable = no' ...''' The second line is the one to change. Okay? import SE Translator = SE.SE ('disable \= yes=disable \= no') print Translator (s) Folks! I am trying to read a file This file has a line containing string 'disable = no' I want to change this line to 'disable = no' ... Did it! - I don't know if it 'takes into account the white spaces' as I don't exactly understand what you mean by that. If need be, just change the substitution definition that makes the Translator to suit your needs. In an IDLE window you can work trial-and-error style five seconds per try. If you want to do other translations, just add more substitution definitions, as many as you want. It will do files too. No need to read them. Like this: Translator ('file_name', 'translated_file_name') If this approach seems suitable, you'll find SE here: http://cheeseshop.python.org/pypi/SE/2.2%20beta Regards Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: newbe's re question
[EMAIL PROTECTED] wrote: Frederic Rentsch wrote: [EMAIL PROTECTED] wrote: Frederic Rentsch wrote: [EMAIL PROTECTED] wrote: All I am after realy is to change this reline = re.line.split('instr', '/d$') into something that grabs any line with instr in it take all the numbers and then grab any comment that may or may not be at the end of the line starting with ; until the end of the line including white spaces.. this is a corrected version from http://python-forum.org/py/viewtopic.php?t=1703 thanks in advance the hole routine is down below.. [code] def extractCsdInstrument (input_File_Name, output_File_Name, instr_number): takes an .csd input file and grabs instr_number instrument and creates output_File_Name f = open (input_File_Name , 'r')#opens file passed in to read f2 = open (output_File_Name, 'w') #opens file passed in to write instr_yes = 'false' #set flag to false for line in f: #for through all the lines if instr in line: #look for instr in the file if instr_yes == 'true':#check to see if this ends the instr block break#exit the block reline = re.line.split('instr', '/d$') #error probily split instr and /d (decimal number into parts) $ for end of line number = int(reline[1]) #convert to a number maybe not important if number == instr_number:#check to see if it is the instr passed to function instr_yes = true: #change flag to true because this is the instr we want if instr_yes = true:#start of code to copy to another file f2.write(f.line) #write line to output file f.close #close input file f2.close [/code] Eric, From your problem description and your code it is unclear what exactly it is you want. The task appears to be rather simple, though, and if you don't get much useful help I'd say it is because you don't explain it very well. I believe we've been through this before and your input data is like this data = ''' CsoundSynthesizer; ; test.csd - a Csound structured data file CsOptions -W -d -o tone.wav /CsOptions CsVersion;optional section Before 4.10 ;these two statements check for After 4.08 ; Csound version 4.09 /CsVersion CsInstruments ; originally tone.orc sr = 44100 kr = 4410 ksmps = 10 nchnls = 1 instr 1 a1 oscil p4, p5, 1 ; simple oscillator out a1 endin /CsInstruments CsScore ; originally tone.sco f1 0 8192 10 1 i1 0 1 2 1000 ;play one second of one kHz tone e /CsScore /CsoundSynthesizer Question 1: Is this your input? if yes: Question 1.1: What do you want to extract from it? In what format? if no: Question 1.1: What is your input? Question 1.2: What do you want to extract from it? In what format? Question 2: Do you need to generate output file names from the data? (One file per instrument?) if yes: Question 2.1: What do you want to make your file name from? (Instrument number?) Regards Frederic I want to pass the file name to the subroutine and return a comment string if it is there maybe it should be simplier. I probily should have the option of grabbing the comment in other related routines. I am pretty ambitious with the main program. I did notice some code in tcl that would be usefull to the app If I compile it.. I am probily not ready for that though.. http://www.dexrow.com Eric, I'm beginning to enjoy this. I'm sure we'll sort this out in no time if we proceed methodically. Imagine you are a teacher and I am your student. This is a quiz. I have to take it and you need to explain to me the problem you want me to solve. If you don't explain it clearly, I will not know what I have to do and cannot do the quiz. If you answer my questions above, your description of the problem will be clear and I can take the quiz. Okay? Frederic instr 1 a1 oscil p4, p5, 1 ; simple oscillator; comment is sometimes here out a1 endin I need to know the file I wan't to grab this from I need to grab this out of the larger file and put it into it's own file, I need to know what instr the user wants. I need to know what file to put it into and it would be usefull to have the comment line returned (if any). I did just get python essential reference 3rd edition.. If there is a better reference on just the subject I am after I would be glad
Re: newbe's re question
[EMAIL PROTECTED] wrote: All I am after realy is to change this reline = re.line.split('instr', '/d$') into something that grabs any line with instr in it take all the numbers and then grab any comment that may or may not be at the end of the line starting with ; until the end of the line including white spaces.. this is a corrected version from http://python-forum.org/py/viewtopic.php?t=1703 thanks in advance the hole routine is down below.. [code] def extractCsdInstrument (input_File_Name, output_File_Name, instr_number): takes an .csd input file and grabs instr_number instrument and creates output_File_Name f = open (input_File_Name , 'r')#opens file passed in to read f2 = open (output_File_Name, 'w') #opens file passed in to write instr_yes = 'false' #set flag to false for line in f: #for through all the lines if instr in line: #look for instr in the file if instr_yes == 'true':#check to see if this ends the instr block break#exit the block reline = re.line.split('instr', '/d$') #error probily split instr and /d (decimal number into parts) $ for end of line number = int(reline[1]) #convert to a number maybe not important if number == instr_number:#check to see if it is the instr passed to function instr_yes = true: #change flag to true because this is the instr we want if instr_yes = true:#start of code to copy to another file f2.write(f.line) #write line to output file f.close #close input file f2.close [/code] Eric, From your problem description and your code it is unclear what exactly it is you want. The task appears to be rather simple, though, and if you don't get much useful help I'd say it is because you don't explain it very well. I believe we've been through this before and your input data is like this data = ''' CsoundSynthesizer; ; test.csd - a Csound structured data file CsOptions -W -d -o tone.wav /CsOptions CsVersion;optional section Before 4.10 ;these two statements check for After 4.08 ; Csound version 4.09 /CsVersion CsInstruments ; originally tone.orc sr = 44100 kr = 4410 ksmps = 10 nchnls = 1 instr 1 a1 oscil p4, p5, 1 ; simple oscillator out a1 endin /CsInstruments CsScore ; originally tone.sco f1 0 8192 10 1 i1 0 1 2 1000 ;play one second of one kHz tone e /CsScore /CsoundSynthesizer Question 1: Is this your input? if yes: Question 1.1: What do you want to extract from it? In what format? if no: Question 1.1: What is your input? Question 1.2: What do you want to extract from it? In what format? Question 2: Do you need to generate output file names from the data? (One file per instrument?) if yes: Question 2.1: What do you want to make your file name from? (Instrument number?) Regards Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: newbe's re question
[EMAIL PROTECTED] wrote: Frederic Rentsch wrote: [EMAIL PROTECTED] wrote: All I am after realy is to change this reline = re.line.split('instr', '/d$') into something that grabs any line with instr in it take all the numbers and then grab any comment that may or may not be at the end of the line starting with ; until the end of the line including white spaces.. this is a corrected version from http://python-forum.org/py/viewtopic.php?t=1703 thanks in advance the hole routine is down below.. [code] def extractCsdInstrument (input_File_Name, output_File_Name, instr_number): takes an .csd input file and grabs instr_number instrument and creates output_File_Name f = open (input_File_Name , 'r')#opens file passed in to read f2 = open (output_File_Name, 'w') #opens file passed in to write instr_yes = 'false' #set flag to false for line in f: #for through all the lines if instr in line: #look for instr in the file if instr_yes == 'true':#check to see if this ends the instr block break#exit the block reline = re.line.split('instr', '/d$') #error probily split instr and /d (decimal number into parts) $ for end of line number = int(reline[1]) #convert to a number maybe not important if number == instr_number:#check to see if it is the instr passed to function instr_yes = true: #change flag to true because this is the instr we want if instr_yes = true:#start of code to copy to another file f2.write(f.line) #write line to output file f.close #close input file f2.close [/code] Eric, From your problem description and your code it is unclear what exactly it is you want. The task appears to be rather simple, though, and if you don't get much useful help I'd say it is because you don't explain it very well. I believe we've been through this before and your input data is like this data = ''' CsoundSynthesizer; ; test.csd - a Csound structured data file CsOptions -W -d -o tone.wav /CsOptions CsVersion;optional section Before 4.10 ;these two statements check for After 4.08 ; Csound version 4.09 /CsVersion CsInstruments ; originally tone.orc sr = 44100 kr = 4410 ksmps = 10 nchnls = 1 instr 1 a1 oscil p4, p5, 1 ; simple oscillator out a1 endin /CsInstruments CsScore ; originally tone.sco f1 0 8192 10 1 i1 0 1 2 1000 ;play one second of one kHz tone e /CsScore /CsoundSynthesizer Question 1: Is this your input? if yes: Question 1.1: What do you want to extract from it? In what format? if no: Question 1.1: What is your input? Question 1.2: What do you want to extract from it? In what format? Question 2: Do you need to generate output file names from the data? (One file per instrument?) if yes: Question 2.1: What do you want to make your file name from? (Instrument number?) Regards Frederic I want to pass the file name to the subroutine and return a comment string if it is there maybe it should be simplier. I probily should have the option of grabbing the comment in other related routines. I am pretty ambitious with the main program. I did notice some code in tcl that would be usefull to the app If I compile it.. I am probily not ready for that though.. http://www.dexrow.com Eric, I'm beginning to enjoy this. I'm sure we'll sort this out in no time if we proceed methodically. Imagine you are a teacher and I am your student. This is a quiz. I have to take it and you need to explain to me the problem you want me to solve. If you don't explain it clearly, I will not know what I have to do and cannot do the quiz. If you answer my questions above, your description of the problem will be clear and I can take the quiz. Okay? Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: How to change font direction?
theju wrote: Well here are some self explanatory functions that I've written for displaying the text vertically and from right to left. As for rotation gimme some more time and i'll come back to you. Also I don't guarantee that this is the best method(cos I myself am a newbie), but I can guarantee you that it works. Here it goes... im=Image.open(imgfile.jpg) draw=ImageDraw.Draw(im) def verdraw(width,height,spacing,a=Defaulttext): for i in range(0,len(a)): draw.text((width,height),a[i],(options)) height+=spacing def right2leftdraw(width,height,spacing,a=Defaulttext): for i in range(0,len(a)): draw.text((width,height),a[len(a)-i-1],(options)) width += spacing options is a 3 field length tuple is mentioned in the PIL-Handbook. Hope you find it useful -Theju Daniel Mark wrote: Hello all: I am using PIL to draw some graphics and I need to draw some texts in vertical direction rather than the default left-to-right horizontal direction. Is there anyway I could do that? Thank you -Daniel I have done a circular 24-hour dial with the numbers arranged to read upright as seen from the center. I remember writing each number into a frame, rotating the frame and pasting it into the dial image at the right place. I also remember using a transparency mask, so the white background of the little frame didn't cover up what it happened to overlap (minute marks). The numbers were black on white, so the frame was monochrome and could be used as its own transparency mask. (This could well be an needlessly complicated approach. When confronting a problem, I tend to weigh the estimated time of hacking against the estimated time of shopping and reading recipes and often decide for hacking as the faster alternative.) Regards Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: stock quotes
Donlingerfelt wrote: I would like to download stock quotes from the web, store them, do calculations and sort the results. However I am fairly new and don't have a clue how to parse the results of a web page download. I can get to the site, but do not know how to request the certain data need. Does anyone know how to do this? I would really appreciate it. Thanks. Hi, Heres's example 8.4 from the SE manual: -- def get_current_stock_quotes (symbols): import urllib url = 'http://finance.yahoo.com/q/cq?d=v1s=' + '+'.join (symbols) htm_page = urllib.urlopen (url) import SE keep = '~[A-Z]+ [JFMAJSOND].+?%~==(10) ~[A-Z]+ [0-9][0-2]?:[0-5][0-9][AP]M.+?%~==(10)' Data_Extractor = SE.SE ('EAT ' + keep) Tag_Stripper = SE.SE ('~(.|\n)*?~= se/htm2iso.se | ~\n[ \t\n]*~=(10) ~ +~= ') data = Data_Extractor (Tag_Stripper (htm_page.read ())) htm_page.close () return data print get_current_stock_quotes (('GE','IBM','AAPL', 'MSFT', 'AA', 'MER')) GE 3:17PM ET 33.15 0.30 0.90% IBM 3:17PM ET 76.20 0.47 0.61% AAPL 3:22PM ET 55.66 0.66 1.20% MSFT 3:22PM ET 23.13 0.37 1.57% AA 3:17PM ET 31.80 1.61 4.82% MER 3:17PM ET 70.24 0.82 1.15% - If this meets your requirements you'll find SE here: http://cheeseshop.python.org/pypi/SE/2.2%20beta Regards Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: How to get the longest possible match with Python's RE module?
[EMAIL PROTECTED] wrote: Frederic Rentsch wrote: If you need regexes, why not just reverse-sort your expressions? This seems a lot easier and faster than writing another regex compiler. Reverse-sorting places the longer ones ahead of the shorter ones. Unfortunately, not all regular expressions have a fixed match length. Which is the longest of, for example, /(abc)?def/ and /(def)?ghi/ depends on the input. Lorenzo Gatti Very true! Funny you should remind me, considering that I spent quite some time upgrading SE to allow regular expressions. Version 1 didn't and could resolve precedence at compile time. Version 2 resolves precedence at runtime by length of the matches and should function correctly in this respect, although it might not function fast enough for speed-critical applications. But then there is in general a trade-off between convenience and speed. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: How to get the longest possible match with Python's RE module?
[EMAIL PROTECTED] wrote: Frederic Rentsch wrote: If you need regexes, why not just reverse-sort your expressions? This seems a lot easier and faster than writing another regex compiler. Reverse-sorting places the longer ones ahead of the shorter ones. Unfortunately, not all regular expressions have a fixed match length. Which is the longest of, for example, /(abc)?def/ and /(def)?ghi/ depends on the input. Lorenzo Gatti Oh yes, and my proposal to reverse-sort the targets was in response to the OP who wanted to generate a regex from a bunch of strings. It should work for that. Frederic -- http://mail.python.org/mailman/listinfo/python-list
Re: How to get the longest possible match with Python's RE module?
Licheng Fang wrote: Basically, the problem is this: p = re.compile(do|dolittle) p.match(dolittle).group() 'do' Python's NFA regexp engine trys only the first option, and happily rests on that. There's another example: p = re.compile(one(self)?(selfsufficient)?) p.match(oneselfsufficient).group() 'oneself' The Python regular expression engine doesn't exaust all the possibilities, but in my application I hope to get the longest possible match, starting from a given point. Is there a way to do this in Python? Licheng, If you need regexes, why not just reverse-sort your expressions? This seems a lot easier and faster than writing another regex compiler. Reverse-sorting places the longer ones ahead of the shorter ones. targets = ['be', 'bee', 'been', 'being'] targets.sort () targets.reverse () regex = '|'.join (targets) re.findall (regex, 'Having been a bee in a former life, I don\'t mind being what I am and wouldn\'t want to be a bee ever again.') ['been', 'bee', 'being', 'be', 'bee'] You might also take a look at a stream editor I recently came out with: http://cheeseshop.python.org/pypi/SE/2.2%20beta It has been well received, especially by newbies, I believe because it is so simple to use and allows very compact coding. import SE Bee_Editor = SE.SE ('be=BE bee=BEE been=BEEN being=BEING') Bee_Editor ('Having been a bee in a former life, I don\'t mind being what I am and wouldn\'t want to be a bee ever again.') Having BEEN a BEE in a former life, I don't mind BEING what I am and wouldn't want to BE a BEE ever again. Because SE works by precedence on length, the targets can be defined in any order and modular theme sets can be spliced freely to form supersets. SE.SE ('EAT be==, bee==, been==, being==,')(above_sting) 'been,bee,being,be,bee,' You can do extraction filters, deletion filters, substitutitons in any combination. It does multiple passes and can takes files as input, instead of strings and can output files. Key_Word_Translator = SE.SE (''' *INT=int substitute *DECIMAL=decimal substitute *FACTION=faction substitute *NUMERALS=numerals substitute # ... etc. ''') I don't know if that could serve. Regards Frederic -- http://mail.python.org/mailman/listinfo/python-list