Re: [Tutor] MemoryError
Liam Clarke wrote: Hi all, I'm playing with a file, and attempting to replace a section with a string, and using the following command - seg=codeSt[element:endInd+len(endStr] codeSt=codeSt.replace(seg, hrefString) At the replace, I get a MemoryError. It's part of a for loop, but it gives the error the first time around. I'm not sure why you're getting the MemoryError, but it'd be easier to figure out if you posted the entire text of the traceback. A few other pointers -- You'll probably get better performance if you put all of this code inside of a function. Even if you're only running it once, putting it in a function allows the interpreter to do some optimization tricks on locals() which can't be done at the module-global level (where you're running now). It's just barely possible that just doing this will help with your MemoryError problem. (You would probably benefit from splitting it into multiple functions, actually. I'd have the code that finds text and url values each in their own function, for example.) Try adding a line in between those two that prints out the value of element and endInd, and then check that those numbers really are valid indexes into codeSt. While you're at it, print out hrefString and make sure it looks like it's supposed to. At the start of your program, you have the following: inp=file("toolkit.txt","r") codeSt=inp.readlines() inp.close() codeSt="".join(codeSt) Since you're not processing by lines, and are explicitly joining all the lines together, why have Python separate them for you? It would be much more efficient to simply use 'codeSt = inp.read()', with no need to join() afterwards. The readlines() method effectively does a read() followed by splitting the result into lines; for your purposes, there's no point in splitting the lines if you're just going to join() them immediately. Instead of finding the start and end index of the segment you want to replace, making a copy of that segment, and then scanning your original string to replace that segment with a new chunk, it would probably make more sense to simply grab codeSt before the segment and after the segment and concatenate them with the new chunk. Thus, your two lines above become codeSt = codeSt[:element] + hrefString \ + codeSt[endInd+len(endStr)] Once again, this would avoid doing the same work twice. Now, I had imagined that codeSt=codeSt+10 would destroy the old codeSt in memory and create a new codeSt. Am I right? Actually, this will probably raise a TypeError (cannot concatenate 'str' and 'int' objects). ;) But yes, rebinding codeSt to a new string should allow the old string to be destroyed (if there are no other references to it). Hope that this helps. Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] MemoryError
Liam Clarke wrote: I'm not sure why you're getting the MemoryError, but it'd be easier to figure out if you posted the entire text of the traceback. Traceback: Line 39: seg=codeSt[element:endInd+len(endStr] MemoryError Hehe. Helpful, no? Actually, it was the "usual bit about in module" that might *be* helpful. ;) Often, something can be determined by the sequence of function calls listed there. Though I suppose, now that I think of it, that since your code is all module-level, there wouldn't be any function stack in this case... Still, in general, when asking for help with something that throws an exception, it's always best to copy & paste the entire text of the exception. One thing that I've noticed, which I thought was just a typo in your original email but which is duplicated again here (it's not present on the web page you linked to) -- you have a mismatched parenthesis in your len() call. It's "[ ... len(endstr]" -- there's no ')' to close the function call. Given that this typo isn't on the web page, I'm not sure whether it's actually there in the code you're running or not. I'd have *thought*, however, that if it *is* present, you'd get a syntax error rather than a memory error, so it's probably not there but you should check it anyhow. :) Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Please help matching elements from two lists and printing them
kumar s wrote: On top of this this process is VERY SLOW on high end server too. That's because, for each line in spot_cor, you're examining every item in spot_int, and if there's a match, you examine every element in spot_int again! If I'm remembering my big-O notation correctly, that makes this O(n*m + m) -- even if it simplifies to O(n*m) (which I think it may), that's still quadratic time -- as the length of your lists grows, your performance will degrade *very* rapidly. Here's a simplified version of your code. I've changed the for loops so that they iterate over the lists directly, instead of iterating over a range and then using that number to index into the list -- the result is the same, but this way is less extra work and easier to read. out = open('sa_int_2.txt','w') for cor_ele in spot_cor: for int_ele in spot_int: cols = split(int_ele, '\t') y = cols[0] + '\t' + cols[1] if x == y: for int_ele2 in spot_int: if y in int_ele2: out.write(int_ele2 + '\n') Remember, every time you use 'in', it means traversing the entire list. Multiple levels of nesting statements that use 'in' causes a polynomial expansion of work. Now, here's how I'd rewrite your code. out = open('sa_int_2.txt','w') element_dict = {} for line in spot_int: cols = split(line,'\t') key = '\t'.join(cols[:2]) element_dict[key] = line for cor in spot_cor: try: value = element_dict[cor] out.write(value + '\n') except KeyError: pass out.close() Note that I iterate through each list only once, so my timing should be O(n + m). First, I preprocess spot_int by putting it into a dictionary. I create keys for the dictionary that are identical to what will be in spot_cor. Then I iterate through spot_cor, and match each element with what's in the dictionary I've made. If I find something that matches, I write it out; if I don't, then I simply move on to the next item in spot_cor. This does make several assumptions. First, it assumes that every line in spot_int will be unique in the first two columns -- that is, I'm assuming that nowhere in the file would you find lines like the following: 5 0 123 5 0 456 If these cases *do* happen, then all but the last such line would be lost, and only the last one would be left in the dictionary (and thus found and written out). In your version, all lines whose first two columns match will be written out. (This may be the source of your "extra" results.) If you *do* need to handle lines like this, then it wouldn't be hard to modify my code for it. Each value in the dictionary would become a list, and matching lines are appended to that list. The line 'element_dict[key] = line' becomes 'element_dict.setdefault(key, []).append(line)', and writing to the file becomes a for-loop instead of a single write. The other assumption that I make is that these files are all of reasonable size to fit into memory. Your code makes this same assumption, too, of course. This assumption should be valid for up to a few tens of thousands (maybe even hundreds of thousands, depending on your hardware) of items. If you have more than this, then your best bet would be to start using a real database. (I've heard good things about mysql and sqlite support in Python...) Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] MemoryError
Liam Clarke wrote: So, I'm going to throw caution to the wind, and try an re approach. It can't be any more unwieldy and ugly than what I've got going at the moment. If you're going to try a new approach, I'd strongly suggest using a proper html/xml parser instead of re's. You'll almost certainly have an easier time using a tool that's designed for your specific problem domain than you will trying to force a more general tool to work. Since you're specifically trying to find (and replace) certain html tags and attributes, and that's exactly what html parsers *do*, well, the conclusions seems obvious (to me at least). ;) There are lots of html parsing tools available in Python (though I've never needed one myself). I've heard lots of good things about BeautifulSoup... Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Difference between for i in range(len(object)) and for i in object
kumar s wrote: > Here is my code: spot_cor=[] Create an empty list... for m in cor: Now, for each element in some other list from somewhere else, ... cols = split(cor,'\t') Ignore the element we've just isolated and try to split the entire list on '\t' ... Traceback (most recent call last): File "", line 2, in ? File "/usr/local/lib/python2.3/string.py", line 121, in split return s.split(sep, maxsplit) AttributeError: 'list' object has no attribute 'split' Yup, the list 'cor' doesn't have a split() method. The string that presumably should be in 'm' would have such a method, though. Here is 2nd way: test_cor=[] for m in cor: ... cols = split(cor,'\t') Once again, you're operating on the list, not the element of the list. Here is my 3rd way of doing this thing: for m in range(len(cor)): ... cols = split(cor[m],'\t') Here, you *are* operating on an element of the list. But if I were to write this segment to be parallel to your previous two attempts, it would be: cols = split(cor[cor],'\t') which probably wouldn't surprise you when it doesn't work... My question: Many people suggested me to avoid iteration over a object using (range(len)) its index and use instead 'Python's power' by using for i in object, instead. However, when I tried that using some data, as demonstrated above, I get error because append method does not work on list. No -- look carefully at the tracebacks, and you'll see that nowhere does it complain about append(), nor does it give the line numbers in which the append() takes place. It complains about split(), and tells you exactly which line the problem is on ('File "", line 2, in ?' -- since you're doing this in an interpreter, there's no filename or function name). Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Problem with python2.4.
Orri Ganel wrote: On Thu, 9 Dec 2004 19:31:22 -0500, Jacob S. <[EMAIL PROTECTED]> wrote: [...] It appears as though pythonw.exe is not working properly in the python 2.4 distribution. I had a similar problem with some of the early versions of 2.4 (beta, release candidate), and it seems to me, looking back, that some of the other programs I had running simultaneously blocked the sockets or something . . . Seeing this comment reminded me of some conversations I've seen in comp.lang.python recently. Apparently newer versions of IDLE create a subprocess to run user-code in (so that IDLE runs in a different interpreter than the code you type into IDLE), and communicates with that subprocess through sockets on the loopback interface (that is, the 'network connection' that connects only to itself). Overly aggressive firewall programs may block those socket operations. I'd check whether XP's built-in firewall is enabled, and if so, check whether it might be blocking connections to loopback / localhost / 127.0.0.1 (all of these indicate the same thing). Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] check_range
Jeff Shannon wrote: if myrange in range(10,90): # "in" is the key word here return True else return False This is, however, the correct solution. :) Or I *should* say, rather, that this is *a* correct solution, in that it will yield the expected answer. Kent Johnson's '10 < x < 90' is a better solution, however -- 'if x in range(...)' creates a list of numbers, and then steps through that list comparing x to each one in turn, while Kent's version makes only two comparisons and no object creations. While one should never prematurely optimize, it's also good to be aware of how much work is done by different options, and in this case 'if x in range()' isn't any clearer than the direct comparisons. I'd think nothing of the extra cost of using range() if it *did* make the code easier to read, but there's no sense in going to extra work for no benefit. :) Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] am I missing another simpler structure?
Blake Winton wrote: def is_leap_year(year): is_leap = True try: datetime.date(year, 2, 29) except ValueError: is_leap = False return is_leap I would write def is_leap_year(year): try: datetime.date(year, 2, 29) return True except ValueError: return False If one insists on single-return style, then I'd prefer to do it this way: def is_leap_year(year): try: datetime.date(year, 2, 29) is_leap = True except ValueError: is_leap = False return is_leap You still have to type 'is_leap' multiple times, but at least it's a little bit more clear which conditions will result in it being True or False. [...] Only having one return point from a function is a long-standing convention that is supposed to make programs easier to read/debug/optimize/prove correct. Indeed, it is supposed (by some) to be better, and is thought by others to sometimes make things more complicated. In the above code, a single return point gives you one place to set breakpoints during debugging, etc, but it also means that you introduce a new variable that you must type at least three times, introducing multiple opportunities for typos. As with most programming choices, single-return has both a benefit and a cost. In some situations the cost can be very large relative to the benefit; in others the cost is very small. I find it best not to be too dogmatic about most such stylistic questions -- I try to stay aware of the costs of a particular approach, but I'll happily use it when the net effect is to make the code simpler and more understandable. Similar to the example that Kent later points out, in my work life I often find myself writing functions (to use as the body of a loop) where a number of unrelated tests must be done before proceeding with processing. (This is actually in an old, crufty dialect of Basic, but the same principle applies) I have a few choices in this case. I can simply write the loop body in-line and use gotos to skip segments if the tests fail (ew). I can write the loop body in-line and use multiply nested if/else statements, but it can get difficult to track what nesting level I'm at. I can use nested functions, each with just one test in it, something like this: def func1(data): result = None if test1: result = func2(data) return result def func2(data): result = None if test2: result = func3(data) return result def func3(data): [...] This gets pretty darn ugly to trace through, especially when I've got six or eight different tests. Or, I can simply use multiple returns: def func(data) if not test1: return if not test2: return if not test3: return # do stuff with data... It really does make it much simpler to track through the code, since I don't care, later in the function, about the specific results of each test, only about whether I should continue afterwards or not. In this case, I'm weighing the cost of multiple returns against the cost of multiple nestings or of using flag variables, and I find multiple returns to be the lowest-cost option. Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python structure advice ?
Dave S wrote: Kent Johnson wrote: Why do you say this is 'cheaty'? A class is basically a collection of data (state) and functions to operate on that state. Sorry for the delay, real world work got in the way ... Well I understand classes to be used when multiple instances are required, I will only need one instance and as such it seemed a bit of a cheat, The trouble is I now pretty well understand the tools, but don't know how you guys use them in the real world. For what it's worth, it seems to me to be perfectly normal to have classes that are only ever intended to have a single instance. For example, you're never likely to need more than one HTML parser, and yet htmllib.HTMLParser is a class... As Kent said, the main point of a class is that you have a collection of data and operations on that data bundled together. Whether you have one set of data to operate on, or many such sets, is mostly irrelevant (though classes are even more valuable when there *are* many sets of data). Defining a class isn't so much a statement that "I want lots of things like this", as it is a declaration of modularity -- "This stuff all belongs together as a unit". Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] About Perl's Integer module
refix) + domain ... .>> So, let's see how this works: .>> complex('site.company.com') 'X3/32/site.company.com' .>> complex('site2.company.com') '6U/zv/site2.company.com' .>> complex('www.python.org') 'ZF/4R/www.python.org' .>> So, each character is generated by looking at the hash (h), grabbing the least-significant six bits, and using the resulting number (which will be 0-63) to look up a character in conv. The hash is then shifted six bits to drop the 'used' bits before grabbing the next chunk. Two of these generated characters are used for each of two directory names. Any given sitename will consistently produce the same four characters. Now, here's a 'batteries-included' function that does much the same thing (though it'll be different characters). .>> def complex2(domain): ... import md5 ... digest = md5.new(domain) ... digeststring = digest.hexdigest() ... names = (digeststring[:2], digeststring[2:4], domain) ... return '/'.join(names) ... .>> complex2('site.company.com') 'b2/37/site.company.com' .>> complex2('site2.company.com') '75/5c/site2.company.com' .>> complex2('www.python.org') '16/95/www.python.org' .>> This uses the md5 module to generate a 'fingerprint' for each domain name. It gets that fingerprint as a long hexadecimal number, and then slices off the first few characters to make the directory names. Now, this method is going to be heavily weighted towards numbers instead of letters, and it can create a maximum of 16^4 (65,536) different directories instead of 64^4 (16,777,216), so you're somewhat more likely to have collisions (multiple sites in a single directory), but it's still not very likely. (That chance can be reduced by using longer names, too. Using three-character directory names gives 16^6 possibilities -- which is equal to 64^4, the same as your perl script.) Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] check_range
R. Alan Monroe wrote: def check_range(myrange): if range(myrange) != range(10,89): return "False" else: return "True" For this to work out, the user's input would have to be a giant string containing 10, 11, 12, 13, etc. Not quite, actually. Presuming that myrange is an integer, range(myrange) will generate a list of integers starting with 0 and continuing up to (but not including) myrange, while range(10,89) generates a list of integers starting with 10 and continuing up to (but not including) 89. These lists can never be equal, because range(10,89) will never include the integers 0-9 but range(myrange) will (unless myrange is less than 10). Unless I mistunderstood your requirements, what you're probably looking for is: if myrange in range(10,90): # "in" is the key word here return True else return False This is, however, the correct solution. :) Presuming again, of course, that myrange is an integer -- but be aware that user input normally comes in the form of strings, so it will be necessary, at some point, to create an integer from that string using int(). Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Comments appreciated
Luis N wrote: This is the most meaningful thing this newbie has ever done. Comments are appreciated: Okay, here's a few thoughts... junk = [] for arg in sys.argv: junk.append(arg) junk = junk[1:] You can write these four lines much simpler as: junk = sys.argv[1:] if len(junk) is 0 and empty == False: sys.exit() else: if len(junk) > 0: trash(junk) if empty == True: can() You can simplify this, too. If empty is True, then you want to call can() regardless of whether you're doing anything else. You can handle that first, and *then* see whether there's junk to delete. This also means that, if you don't have junk to delete, you can simply do nothing, instead of explicitly calling sys.exit(). In addition, you don't need to explicitly test against True -- empty will already be true or false on its own, so comparing it inside an if statement doesn't gain you anything. if empty: can() if len(junk) > 0: trash(junk) Also, even though this is intended to be a quick shell script, it's not a bad idea to make everything except function defs into a little main() function, and call it in a script-only section. This gives you a bit more modularity, pulls all of your actions into a single place, and lets you avoid using global variables. def main(junk): trashcan = os.path.expanduser("~/.trashcan") empty = False if "-e" in junk: empty = True junk.remove("-e") if not os.path.exists(trashcan): os.mkdir(trashcan) if empty: can() if len(junk) > 0: trash(junk) if __name__ == '__main__': main(sys.argv[1:]) Notice that I've also changed your trashcan from explicitly stating a home directory to getting the home directory for whoever the current user is. You can refine main() further, too -- for instance, instead of setting an empty flag, you could just call can() as soon as you find the -e option. Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] O.T.
I'm 36, unmarried, male, and live in Seattle, Washington (USA). I've dabbled with computers and programming on and off since junior high (around 1980), but have only gotten serious about it in the last 10 years or so (almost entirely self-taught), and have only been employed in the field for about 5 years. I had two years of college (nominally majoring in chemistry) at the University of Alaska (the state where I grew up) before dropping out, moving to Seattle, and frittering away my young adulthood. ;) I work for a small company that does electronic payment processing and check management. Our system is built around an old Pick database (ugh), and most of my programming is in Pick Proc (a shell-script-like, but truly horrible, language) and Pick's dialect of Basic (which is only 20 years out of date...). As we're moving more towards integrating our server with desktop PCs, though, I've been able to use Python for a few projects, and I often use it for interactively exploring data files and doing sysadmin-type work. Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to put my functions in an array
Mohamed Lrhazi wrote: def addvirt(): pass def remvirt(): pass PROVISION_ACTIONS=[('addvirt','Add Virt'),('remvirt','Remove Virt'),] formhandlers={} # this works formhandlers["addvirt"]=addvirt formhandlers["remvirt"]=remvirt # this does not work: for verb,verb_desc in PROVISION_ACTIONS: if callable(verb): formhandlers[verb]=verb I tried a few different syntaxes but to no avail... do I need things like: getattr()? You don't say how this fails, which would be very helpful to know. But I think I can guess what's happening. When you're calling 'callable(verb)', at this point verb contains a string which is a function's name. It is *not* the function itself. The string is, of course, not callable, so nothing gets added to formhandlers. Even if you took out that test, though, you'd end up with a dictionary where for a given key, the value is the same string that was used for the key, because verb is only a string. For this to work, you need to have two separate things -- a string by which to identify the function, and a reference to the function object itself. In the working code, you do this. By putting the name (that you're using as the dictionary key) in quotes, you're specifying a string, and by *not* putting the value (on the right of the = sign) in quotes, you're referring to the function object. There's a couple of ways you can do this. One is by adding a reference to the function to your list, something like this: PROVISION_ACTIONS = [('addvirt', "Add Virt", addvirt), ...] for verb, verb_desc, func in PROVISION_ACTIONS: if callable(func): formhandlers[verb] = func If you can't make that change to PROVISION_ACTIONS, then you may be able to use the name strings to pull function references from your module's global dictionary -- for verb, verb_desc in PROVISION_ACTIONS: func = globals()[verb] if callable(func): formhandlers[verb] = func though you'd probably want to put that globals() lookup in a try/except block to catch any KeyErrors. Note that if the functions were in a different module, you could retrieve them from that module with getattr(), rather than using the globals() dict. import func_module # ... for ... func = getattr(func_module, verb) # ... Once again, you should probably wrap that in a try/except block (this time looking for AttributeErrors). Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] My best GUI app so far.
so I'm not sure offhand.) Then your button bindings can simply be self.bl = [ self.make_adddigit_callback('0'), self.make_adddigit_callback('1'), self.make_adddigit_callback('2'), ... ] Or even -- self.bl = [self.make_adddigit_callback(digit) \ for digit in '0123456789'] Remember, there's nothing particularly special about lambdas -- you can create and pass around regular named functions, too. Each time that make_adddigit_callback() is called, it creates and returns a new function object which captures the current value of 'digit', in exactly the same way that lambda does. A function object (whether named with def, or lambda) like this, which captures a variable's current state, is called a closure. Closures are indispensible for GUI callbacks like this, and many people automatically turn to lambda when they want a closure. For me, though, having a proper def statement somewhere feels clearer. (The merits of lambda vs. def'd functions are a frequent subject of heated debate on comp.lang.python, so if you prefer to stick with the lambdas in this case, I'm sure you'd be able to find plenty of people to support you... ;) ) Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class instance with identity crisis
Barnaby Scott wrote: class Damson: def __str__(self): return 'damson' def dry(self): self = Prune() class Prune: def __str__(self): return 'prune' weapon = Damson() weapon.dry() print weapon [...] but something in me suggests it should produce prune After all, 'self' refers to the instance 'weapon'. Ah, but 'self' is a method-local name. You're re-binding that name, not affecting the object (previously) pointed to by the name. And of course, when the method returns, those local bindings go away. Obviously one could reassign weapon to a Prune outside the class definition, but I was hoping to write something in which, given certain circustances arising, the instance would change itself into something else. As others have mentioned, you can change the type of the object by assigning to self.__class__, but this can get a bit hairy. Your class/instance knows nothing about what names it may be bound to, so it can't rebind those names to a different object (i.e. class Damson, and any instances you create, know nothing of the name 'weapon'). I tend to favor the explicit approach of having weapon.dry() *return* a different object, and then using 'weapon = weapon.dry()'. But if you really need to have objects that change their type as a side-effect of a method call, you can use a proxy or adapter -- in essence, you have a class that can *contain* either a Damson or a Prune, and which forwards method calls / attribute accesses to its contained object. Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to create a key-value pairs with alternative elements in a list ... please help.
kumar s wrote: Problem: How do i capture every alternative element in list a: I am unable to pump the a,b, and c into keys list and apple, boy,cat into vals list. In a sufficiently recent version of Python, you should be able to use an extended slice with a stride -- keys = a[::2] vals = a[1::2] (Note that this is untested, as I don't have a recent version of Python handy at the moment; I'm on 2.2 here, which doesn't have extended slices.) Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Regular expression re.search() object . Please help
Liam Clarke wrote: openFile=file("probe_pairs.txt","r") probe_pairs=openFile.readlines() openFile.close() indexesToRemove=[] for lineIndex in range(len(probe_pairs)): if probe_pairs[lineIndex].startswith("Name="): probe_pairs[lineIndex]='' If the intent is simply to remove all lines that begin with "Name=", and setting those lines to an empty string is just shorthand for that, it'd make more sense to do this with a filtering list comprehension: openfile = open("probe_pairs.txt","r") probe_pairs = openfile.readlines() openfile.close() probe_pairs = [line for line in probe_pairs \ if not line.startswith('Name=')] (The '\' line continuation isn't strictly necessary, because the open list-comp will do the same thing, but I'm including it for readability's sake.) If one wants to avoid list comprehensions, you could instead do: openfile = open("probe_pairs.txt","r") probe_pairs = [] for line in openfile.readlines(): if not line.startswith('Name='): probe_pairs.append(line) openfile.close() Either way, lines that start with 'Name=' get thrown away, and all other lines get kept. Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Re: communication between java and python?
Lee Harr wrote: I'm trying to communicate between Python and Java and using os.popen(). But thing dont work...The Java program reads strings from stdin and the python program just writes to stdout. [...] """ popen(command[, mode[, bufsize]]) Open a pipe to or from command. The return value is an open file object connected to the pipe, which can be read or written depending on whether mode is 'r' (default) or 'w'. """ So, I do not believe that you can both write to and read from a file handle opened with popen. Not only that, but access to the file-like pipe objects is probably buffered. You'll want to call pipe.flush() after writing to it, or the child process won't actually see what you've written. Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Regular expression re.search() object . Please help
Jacob S. wrote: I assume that both you and Liam are using previous-er versions of python? Now files are iterators by line and you can do this. openFile = open("probe_pairs.txt","r") indexesToRemove = [] for line in openFile: # [...] My version of Python isn't *that* old (IIRC this works since 2.2, which is what I usually use), I'm just in the habit of using readlines(). I suppose that, in a case like this where the filesize is not insignificant, it *would* be worthwhile to take advantage of the file iterator to avoid having that fairly large list in-memory... Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] file-like object
Terry Carroll wrote: On Fri, 14 Jan 2005, Chad Crabtree wrote: class _macroString(object): def __init__(self,s): self.macro=s self.list=self.macro.split("\n") for n,v in enumerate(self.list): self.list[n]=v+'\n' Is this for loop a safe technique, where the list you're enumerating over in the for statement is the same as the one being updated in the loop body? I always avoid things like that. In this case it should be safe. This changes the string at each index in the list, but it doesn't change the length or ordering of the list. That's where the problems come in, because the for loop doesn't know that the list "shape" has changed. But your caution is generally a good idea. :) I'd have probably written the above as: self.list = [line+'\n' for line in self.list] Well, actually, I'd have avoided saving the intermediary state and simply done all the list processing at once: self.list = [line+'\n' for line in self.macro.split('\n')] Either way, though, I'm creating a new list rather than modifying the old list in-place, which avoids the risk of accidentally changing the list's "shape" and throwing off the loop. Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Re: glob or filter help
Barnaby Scott wrote: For anyone who doesn't like lambda, how about import os def get_fles(exts, upd_dir): return [i for i in os.listdir(upd_dir) if i.split('.')[-1] in exts] Better would be: def get_fles(exts, upd_dir): return [fname for fname in os.listdir(upd_dir) if \ os.path.splitext(fname)[-1] in exts \ and not fname.islink() ] (This is split into three lines for readability, but can be entered as a single line. Also, the '\' line-continuation is optional, as Python will see that the list comp is still open and automatically continue the line...) Using os.path.splitext() to get the extension is safer and more portable than simply splitting on '.', and it's self-documenting too! (A month from now, you might need to think a moment to figure out why you're splitting on '.', but the very name os.path.splitext() tells you about the intent.) Note that there's a slight difference here, in that exts will need to list extensions *with* the leading '.' because splitext() will leave it on -- >>> os.path.splitext('filename.txt') ('filename', '.txt') >>> I've also added a second clause to ensure that returned files are not links, as per the rest of the O.P.'s spec. Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Syntax Check
Chad Crabtree wrote: I'm trying to make a macro system that's work by just doing this import macro # [...] Perhaps you could turn things around, and make your macro preprocessor into an import hook? I.E., you'd use it like -- import macro module = macro.import("module_with_macros"[, macro_list]) module.do_stuff() Not sure if you'd need to have a list of macros in the module to be imported, or not. Perhaps the macro module would hold a list of currently active macros, instead... In any case, this (I think) gives you a chance to interrupt the import process and modify the target module before the Python parser gets it, which should enable you to avoid the SyntaxError problems. (Of course, I've never messed around with hooking __import__(), so I could just be talking out of my ...) Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Better structure?
Jacob S. wrote: I don't know who's going crazy here... but I checked that straight from the python 2.4 interpreter... >>> a = "go on long buddy" >>> a.lstrip('gonl') ' on long buddy' >>> a.lstrip('gonl ') 'buddy' >>> Note that in the second case, I've included a space in the lstrip() parameter. lstrip() is essentially saying "remove all leading characters until you find a character that's not in this sequence" -- a space counts as a character. (Took me trying it out before I saw this, so don't feel bad. ;) ) Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Better structure?
Jacob S. wrote: So, how would one go about this in a non broken code way? Don't they have something like what I'm requesting. No, but it's pretty easy to do: def exact_lstrip(astring, stripstring): if astring.startswith(stripstring): astring = astring[len(stripstring):] return astring [...] Also why shouldn't string methods include stuff like lstrip which do precisely what I request? Maybe it's because other people would have different expectations? The current implementation of strip() (including lstrip() and rstrip()) seems to work well for the most common case, and I'm not sure that your expectation is necessarily more generally useful than the current behavior. Especially given that your behavior is the one that's easier to hand-code if it's desired. Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Are you allowed to shoot camels? [kinda OT]
Max Noel wrote: On Feb 3, 2005, at 09:48, Alan Gauld wrote: Pythons lambda feature is a bare minimum (and Guido wants to remove it!). Does he? Damn, just when I was learning functional programming! (in Haskell, if you're curious ^^) However, Python doesn't need lambdas to be able to write in a functional style. Functions are first-class objects and can be passed around quite easily, and IIRC Python's list comprehensions were borrowed (though probably with notable modification) from Haskell. Keep in mind that both lambdas and named functions are created at runtime, so the creation of both is fully dynamic. Indeed, there are only a few differences between lambdas and named functions in Python: - Anonymous vs named - Single expression vs suite of statements - Inline vs. pre-created Note that the second of these is a consequence of the third -- given Python's block-indentation-based structure, there's no good way to inline a multi-statement suite (how many of those statements belong to that 'if' suite?). Statements need to have a clear indentation level, and while one can sometimes fudge that for a single statement, it gets exponentially messier as the number of statements goes up. I'd also argue that the inline nature is the *true* differentiating feature of lambdas -- the fact that they're anonymous is relatively minor. Consider, also, that if they weren't inline then you'd need a name to refer to them by... and at that point, you *have* a 'normal' function. So, while there are some advantages to having single-use callables be defined inline (i.e. lambdas), their removal from Python (which wouldn't happen before the mythical Python 3k anyhow) isn't likely to be as devastating as some might lead you to believe. ;) It certainly won't prevent you from using Python for functional programming... (And personally, I suspect that if lambdas *are* removed, they will be replaced with a different construct that will fill the same needs in a more Pythonic way...) Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Are you allowed to shoot camels? [kinda OT]
Alan Gauld wrote: There is no perfect language, and very few truly bad languages - they never get out of the lab - they all have something that they are good at and from which we can learn! Heh, I'd look at that a bit differently -- I think that there's a *lot* of bad languages, it's just that we're spared ever hearing about the majority of them because they don't ever get very far. ;) (But then, at my job I'm stuck using a horrible Frankenstein's monster of a proprietary language on a daily basis, so I can't help but believe that there's plenty more awful languages around that didn't happen to be "rescued" from oblivion by an accident of history...) Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Are you allowed to shoot camels? [kinda OT]
Alan Gauld wrote: However, Python doesn't need lambdas to be able to write in a functional style. I disagree Jeff. It does need lambdas to do FP properly, and better lambdas than we have currently. What it doesn't need is the lambda keyword and syntax - although pesonally I like lambda since it is descriptive! Well, we'll have to continue to disagree on that. ;) Personally, I can't help but think that 'lambda' is descriptive only to people who've experienced it elsewhere, and that that does *not* include the majority of the programming community, but I could be mistaken. :) Functions are first-class objects and can be passed around quite easily, Yes, but lambdas are more than first class functions, they are anonymous functions! In fact really just callable code blocks, not necessarily functions in the strictest sense (except that every callable in FP is a function...! ;-) Well, given that in Python a function is just a callable code block that's bound to a name... ;) Personally, I fail to see why having an anonymous function is such a huge conceptual advantage, no matter how many times this is proclaimed as truth by lambda-users, but again this is just my own impression. Having to define every function before using it would be a big hassle and make code less readable IMHO. Here, ISTM that you're emphasizing the in-line nature of lambdas as being their key usage point... And personally, I prefer to have a glossary of terms rather than having to decipher jargon by context. ;) only a few differences between lambdas and named functions in Python: - Anonymous vs named the key feature Again, I fail to see why this is such an advantage -- I've seen assertions that it is, over and over again, but never any convincing evidence - Single expression vs suite of statements A python restriction. Well, I *did* specify that I was talking about 'in Python'... ;) I'd also argue that the inline nature is the *true* differentiating feature of lambdas -- the fact that they're anonymous is relatively minor. I agree, if I had an inline mechanism that forced me to provide a name I could just use 'f' over and over and not feel too cheated, but its nicer not to have an artificial name when theres no need. Personally, I prefer to have the opportunity to provide a meaningful name, and don't see where a generic name is any more restrictive than having no name, but again, maybe that's just me. So, while there are some advantages to having single-use callables be defined inline The other advantage is the huge conceptial advantage that real lambdas confer. The breakthrough idea of def f(x): return x+x being the same as f = lambda x: x+x is only possible to demonstrate if you have lambda to start with. And yet that concept of a function name being just another variable and the callable code being an object in its own right becomes much more obvious in my opinion. lambda is a learning tool which shows what is really happening whereas def is just syntactic sugar. Hm, I understood the idea of functions being just code objects that were bound to a name, and could be passed around, stored in collections, and effectively renamed, well before I really got a hold on lambdas as anything more than some confusing bit of magic. Of course, I started in C, where I was fairly comfortable with the idea of function pointers; function objects are a pretty simple step up, abstraction-wise, from that. I suppose that one might argue that I *still* just don't really get lambdas (and I wouldn't argue with that). I can see some advantages to small inline functions, though I suspect that a more-explicit currying mechanism (such as the proposed partial() higher-order function) could easily replace such uses. I'm sorry to say, though, that the supposed advantages of anonymity come across as little more than handwaving assertions to me, no matter how sincerely they're intended. (I've just started to read through SICP, to pick up some lisp/scheme, in hopes of understanding the appeal a bit better, so maybe there's hope for me yet. ;) ) Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Are you allowed to shoot camels? [kinda OT]
Max Noel wrote: On Feb 3, 2005, at 23:41, Jeff Shannon wrote: (But then, at my job I'm stuck using a horrible Frankenstein's monster of a proprietary language on a daily basis, so I can't help but believe that there's plenty more awful languages around that didn't happen to be "rescued" from oblivion by an accident of history...) Yeah. Sometimes I read a little bit of Wikipedia's "Esoteric Programming Languages" page, and some of them just leave me in awe. Brainfuck (and its variant Ook!) and INTERCAL ("GOTO is considered harmful, so we removed it -- INTERCAL uses COME FROM instead") are already quite impressive, but the very idea of Befunge makes my brain want to explode. Especially that extension to the language that allows one to write N-dimensional programs. :D The difference here is that those are languages that were *intended* to be brain-melting. The language I'm talking about (Pick Proc, aka UHL) was intended to do real work with -- though at times I think it was designed by a brain-damaged lemur that was huffing paint fumes. For example, every line (except flow-control statements i.e. 'if' and 'go' (there's a few other exceptions as well, but anyhow...)) must begin with a single character that denotes what the line does - 'c' for comment, 'o' for output (print to terminal), 'h' to build a command, 'p' to execute that command... empty lines are forbidden. Note also that the position *after* the final newline character is considered a line, and therefore a file cannot end with a newline. Especially when combined with several of the utilities that it's commonly used to script for, it begins to approach Perl in indecipherability, without even having the excuse of being largely non-alpha characters. I'd consider writing a Python extension that would interact with the system such that I wouldn't need to use this awful little scripting language, but that would require more effort and thought than I'm willing to invest in learning the details of this system. Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Are you allowed to shoot camels? [kinda OT]
Smith, Jeff wrote: IMHO, if/elif/else statements are far more abused than either switch or ternary but I certainly wouldn't argue they should be removed from the language. IMHO, if it's true that if/elif/else statements are more abused than ternaries, then it's only because they're *used* far more often than ternaries. I'd say that the percentage of uses which could count as abuse is *far* higher for ternary than for if/elif/else. And I avoid (and recommend against) Python's "a and b or c" trick for similar reasons -- it *is* a trick. A 'real' ternary operator is confusing enough; this trick is more readable (words instead of opaque symbols) but more difficult to write correctly given the constraints on 'a'... Maybe I'm just weird, but I just don't find so much benefit to putting *everything* in-line. Occassionally it improves readability, but more often it obscures and obfuscates. Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Are you allowed to shoot camels? [kinda OT]
Alan Gauld wrote: As an aside, I did try to create a lambda based solution but was unable. Let me know what's wrong: ftable = { 'a' : lambda: print 'a', SyntaxError: invalid syntax I did say "if Python had *proper* lambdas..." Unfortunately Python insists on only having *expressions* as lambdas and since print is a command not a function you can't use it in Python lambdas! Dumb or what??! So you are stuck with predefining a bunch of one liner functions and then creating a dictionary or going back to if/elif chains, which is where we came in... :-) Well, in this particular case, if one really wants to use lambdas then one could (after importing sys, of course) replace the print statement with a call to sys.stdout.write() -- ftable = { 'a': lambda: sys.stdout.write('a\n'), ... } Note that sys.stdout.write() will *not* automatically add the newline that print does (which is why I've specified it in the above sample). Indeed, print can do all sorts of odd things with whitespace, leaving sys.stdout.write() as the best way to have real control over your output anyhow... Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Are you allowed to shoot camels? [kinda OT]
Smith, Jeff wrote: Jeff, It looks like that finally is the simplest expression of the original switch statement: import sys def p(): pass ftable = { 'a' : lambda: sys.stdout.write('a\n'), 'b' : lambda: sys.stdout.write('b or c\n'), 'c' : lambda: sys.stdout.write('b or c\n'), 'd' : p } ftable.get(var, lambda: sys.stdout.write('default case\n'))() I do note that it took this group of experienced programmers several tries to impliment this simple switch statement without actually using switch. I dare say with standard switch syntax we would've had it right the first time :-) I wasn't following this thread all the way through, but to be honest, I'd have solved this differently -- that may be the best "direct translation" of some switch statement, but that doesn't mean it's the best-fit solution here. ISTM that, given the desire to print some text (or nothing) based on the contents of a variable, I would *not* handle the output inside the "switch" -- that is, I'd (conditionally) print a value from a string-containing dictionary, rather than use a table of functions that print strings. table = { 'a': 'a', 'b': 'b or c', 'c': 'b or c', 'd': None } result = table.get(var, 'default case') if result: print result This, to my mind, is much cleaner -- you're factoring out the repeated code, whether print statement or call to sys.stdout.write(), reducing the complexity of the dict. You're making flow control much more straightforward. You're making the whole thing easier to read. The key, here, is that instead of saying "I want a switch, how can I implement that in Python?", I've taken the approach of "The end result I want is ***; what tools does Python offer to achieve that?" This conceptual shift is, IMHO, *the* most important mental hurdle in learning a [second/third/n-th] language. Jeff Shannon Technician/Programmer Credit International ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] dictionary dispatch for object instance attributes question
On Tue, 15 Feb 2005 17:19:37 -0500, Brian van den Broek <[EMAIL PROTECTED]> wrote: > My Node class defines a _parse method which separates out the node > header, and sends those lines to a _parse_metadata method. This is > where the elif chain occurs -- each line of the metadata starts with a > tag like "dt=" and I need to recognize each tag and set the > appropriate Node object attribute, such as .document_type. (I do not > want to rely on the unhelpful names for the tags in the file format, > preferring more self-documenting attribute names.) In addition to using setattr(), I'd take a slightly different approach to this. (This may just be a matter of personal style, and is not as clearly advantageous as using setattr() instead of exec, but...) .class Node(object): .metadata = {'dt': 'document_type', 'something': 'some_other_field', ...} .def __init__(self): # .def update(self, **kwargs): .for key, value in kwargs.items(): .try: .attr_name = self.metadata[key] .except KeyError: .raise ValueError("Invalid field type '%s'" % key) .setattr(self, attr_name, value) For starters, I've made metadata a class attribute rather than an unconnected dictionary. This seems conceptually nicer to me. In addition, update() can now modify several attributes at once, at the cost of a bit of extra parsing up front. Supposing that your node header looks like this: .header = "dt=text/plain;something=some_value;last=some_other_thing_here" Now, we can break that into fields, and then split the fields into a name and a value -- .tags = {} .for field in header.split(';'): .name, value = field.split('=') .tags[name] = value . .n = Node() .n.update(**tags) You can even simplify this a bit more, by rewriting the __init__(): .def __init__(self, **kwargs): .if kwargs: .self.update(**kwargs) Now you can create and update in a single step: .n = Node(**tags) You could also put all of the splitting into fields in a method, and when __init__ gets a single string as its argument simply pass it to that method and update with the results... --Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Queued threads
On Wed, 16 Feb 2005 16:50:07 +1300, Liam Clarke <[EMAIL PROTECTED]> wrote: > Oops, you probably want to do this then- > > for i in range( 0, 3 ): > oThread = Thread( target=mainFunction ).start() > > while oThread: > print 'sleeping 3 seconds' > time.sleep( 3 ) Probably not. Note that, since oThread's value is not changed in the body of this while loop, you will either never execute the body (if oThread is false) or execute it infintely many times (if oThread is true). I doubt that's the desired behavior. ;) In this case, since Thread.start() apparently always returns None, the while loop is effectively a no-op. However, if it *did* get triggered, it would do so immediately after the first thread [which returned a true value from start()] was started -- preventing later threads from being started because the main program is stuck in this endless loop. You could perhaps rewrite the whole thing like this: .for i in range(3): .mythread = Thread(target=mainFunction) .mythread.start() .while mythread.isAlive(): .print "sleeping 3 seconds [main thread]" .time.sleep(3) Though as others have said, if you're not starting the second thread until the first is finished, then you might as well just make it explicitly sequental and not bother with threads: .for i in range(3): .mainFunction() If you actually want the threads to process concurrently, and simply wait until all of them are done, you could do this: .threadlist = [] .for i in range (3): .mythread = Thread(target=mainFunction) .mythread.start() .threadlist.append(mythread) .for thread in threadlist: .thread.join() The join() method will wait until that thread is finished, and then return. If the thread is already finished when it's called, it returns immediately. Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] dictionary dispatch for object instance attributes question
On Tue, 15 Feb 2005 23:48:31 -0500, Brian van den Broek <[EMAIL PROTECTED]> wrote: > Jeff Shannon said unto the world upon 2005-02-15 21:20: > > On Tue, 15 Feb 2005 17:19:37 -0500, Brian van den Broek > > <[EMAIL PROTECTED]> wrote: > > > > For starters, I've made metadata a class attribute rather than an > > unconnected dictionary. This seems conceptually nicer to me. > > The problem is that my Node instance live in a TP_file class instance, > and the way my code is now, the TP_file instance also needs to see the > metadata dict. There are a few tags, which if present in any Node of > the file make me want to treat the entire file a bit differently. (Of > course, here is the place where my novice-designer status is most > likely to be bitting me.) So, that's why I have it as a module level > object, rather than within a class. (I do, however, see your point > about it being neater.) Okay, that makes sense. You have two different classes (the TP_file class and the Node class) that need access to the same information, so yes, having it at the module level lets them share it more effectively. (Alternately, since it sounds like the TP_file class is where all of the Node instances are created, you *could* decide that the metadata belongs as part of the TP_file, which would then actively share it with Node... but what you've got sounds like a very reasonable plan, so at this point I wouldn't worry about it.) > > In addition, update() can now modify several attributes at once, at > > the cost of a bit of extra parsing up front. > > The metadata all occurs one element to a line in my original file. > [...] Maybe I'm still missing a better way, but as I am processing > line by line, each line with one element, I don't see how to use this > cool looking multiple elements at once approach. Yes, if you know that you will only have one header per line, then it's reasonable to process them one line at a time. You could alternatively have the TP_file gather all the header lines for a given node into a list, and then process that list to create the Node instance, but given the specifics of your case you probably wouldn't gain anything over your current approach by doing so. This is what makes programming so interesting -- there's so many different choices possible, and which one is best depends on a large number of factors. When writing a program for some task, the best design for a particular set of circumstances may be completely different than the best design for a somewhat different particular set of circumstances -- and the best design for general usage is probably an altogether different thing still. Good luck! Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help needed with script to batch-create shapefiles
On Wed, 16 Feb 2005 21:37:10 +, Chris Bromley <[EMAIL PROTECTED]> wrote: > Any help would be greatly appreciated! Others have already pointed out that we will have a hard time helping without a bit more information. But I've noticed something odd in your code -- it probably doesn't have anything to do with your problem, but it seems like an awkward idiom to me. > fc = fcs.next() > > while fc: > # [...] > fc = fcs.next() This, it seems to me, is equivalent to (but less readable than) the following: .for fc in fcs: .# [...] If you're going to do something with every member of a list, then it's much more straightforward to use a for loop (which automatically tracks the iteration) than to use a while loop and manually adjusting the loop-controlling expression. Actually, it occurs to me that this *might* cause a confusing result in your code. Presuming that fcs is a standard iterator (as your usage of next() suggests), then calling next() on an exhausted iterator will raise a StopIteration exception. The for loop will automatically handle that, but with your while loop it would be caught by the following bare except statement. That means that you'll run (what I presume to be) your error-handling code even when you successfully convert every member of fcs... Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Active Python
On Thu, 17 Feb 2005 15:54:43 -0800 (PST), Terry Carroll <[EMAIL PROTECTED]> wrote: > On Wed, 16 Feb 2005, Robert Campbell wrote: > > > I am not a programmer, but have decided to learn Python. I am wondering > > if anyone has used the Activestate ActivePython and what are the > > advantages/disadvantages of using it rather than the standard Python > > tools. > > If you're on Windows, I recommend it. > > It is the full Python, plus some Windows extensions. I fully agree. ActivePython contains everything that you'd get from the standard distribution, plus extra tools that are especially useful under Windows. (I like PythonWin a lot more than IDLE...) > The only downside I've encountered is that, as of 2.4, it no longer > includes the Help files in their original HTML format. Instead, there's > just one big help file in Windows Help format. > > I prefer the HTML, because I can then run searches against it from > outside the help system. Interesting -- I prefer the CHM (Windows helpfile), because it's internally indexed. I feel that the internal search is more convenient than external searches would be. But I suppose that there's room for reasonable people to disagree, here. :) Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] SubClassing
On Fri, 25 Feb 2005 05:54:39 -0200, Ismael Garrido <[EMAIL PROTECTED]> wrote: > def __init__(self, this, that, new): > Parent.__init__(self, this, that) #note self > self.new = new If the paren's init t has a lot of possible arguments, it may be easier to do things this way: class Child(Parent): def __init__(self, new, *args, **kwargs): Parent.__init__(self, *args, **kwargs) self.new = new This way, the Child class doesn't need to know or care about what parameters get passed on to Parent; it uses the ones it needs, and passes all the rest on. Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Re: How do you share a method (function) among several objects?
On Sun, 27 Feb 2005 20:20:19 +0200, Xif <[EMAIL PROTECTED]> wrote: > There are two major classes: > > 1) an Excel class, that represents of the whole Excel program > 2) a Cells class, that abstracts retrieval and editing of cells. > > [...] > > The difference between the 2 classes is that a Cells instance just > converts the generator into a list and returns it: > > # > return list(getCells(self.sheet, cells)) > # > > while an Excel instance returns the values of the cells: > > # > return [cell.Value for cell in getCells(self.sheet, cells)] > # Why not have the Excel class make use of the Cells class? That is, you construct a Cells object with the appropriate parameters, use it to get the list of cells, and then iterate over that list getting values? You could probably find many other places in the Excel class where it could be simplified by delegating to a Cells instance, too... Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] sys.argv[1: ] help
On Sun, 27 Feb 2005 17:55:54 +, Richard gelling <[EMAIL PROTECTED]> wrote: > > No What I get if I was to type in > ./arg1.py a b c > > All I get is > [] It sounds as though the command shell is not passing along the additional parameters. Try opening Windows Explorer, and go to the Folder Options (in the Tools menu, IIRC). Go to the "File Types" tab, find PY (Python File), and click the "Advanced" button. In the resulting dialog, select the "open" action and click "edit", then look at the command line that it's using. You want something that looks like: "C:\Python23\python.exe" "%1" %* The '%*' bit at the end is what I suspect may be missing in your settings. (There's some chance that cmd.exe uses a different set of settings than Windows Explorer does, in which case you'll have to research that independently. I know that you can use the "assoc" command to associate the .py extension with the Python.File filetype, but I'm not sure how to create filetypes or change actions that are taken upon filetypes if it's different from the Explorer settings) Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Criticism / Suggestions
On Wed, 02 Mar 2005 01:17:28 -0500, Bill Kranec <[EMAIL PROTECTED]> wrote: > [...] I wanted to be able to define > multiple tournament objects off of the same roundlist, to avoid > generating the list every time a new object is created. I think what I > really want to do is have a separate Round class, from which Tournament > inherits the list of rounds. I have started to implement something like > this in my most recent version, but haven't finished it yet. ( I need > to understand class inheritance better. ) This sounds like a good idea, but inheritance is probably not the right way to solve it. Every Tournament contains a list of Rounds, but it's probably not accurate to say that a Tournament is a type of Round. (Inheritance works best when it describes an "is-a" relationship, not a "has-a" relationship.) It's probably better to have Tournament and Round be independent classes, but have Tournament instances hold a list of Rounds (which may be passed in during initialization, or may be added later). This is called "composition", and is just as important (or perhaps more important) of an idea as inheritance, even though inheritance gets all the press. ;) Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Linked List
On Sat, 5 Mar 2005 06:20:40 -0800 (PST), Shitiz Bansal <[EMAIL PROTECTED]> wrote: > In order to explain wat my problem is, here is an > example code. Its not exactly what I am doing, I am > using multiple threads and a rather complicated code > so try and understand the sense rather than the code > itself. > > >>> myls=range(50) > >>> for i in myls: > print i > if i==20: > myls.insert(5,5) > > The point is, the list(both size and elements) is > changing even as it is being operated upon. My first thought was to say, "Use a queue.Queue." But it appears that you need to be able to do more than just add items at the end of the queue. I suspect that what you need is along the lines of a "priority queue". That is, something that works approximately like a queue, but when you add items to it, you also specify a priority for them. Then, when you retrieve an item from the queue, what you get is not necessarily the first-inserted item, but rather the item with highest priority. You might want to check the Cookbook to see if there's a priority queue recipe there. If not, I suspect that Google can be convinced to yield something... Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] 2d list matrix 7 x 75 problem
On Sun, 06 Mar 2005 09:49:43 +, Dave S <[EMAIL PROTECTED]> wrote: > I need to generate a list 2d matrix of the kind ... > > [['', '', '', '', ''], ['', '', '', '', ''], ['', '', '', '', ''], ['', > '', '', '', ''], ['', '', '', '', '']] > > except its dimensions need to be 7 x 75. I thought I had it sorted with > > map2 = [ [''] *7 ] *75 > > until the coding screwed up & I realised I had 75 references to the same > list :-( Try: map2 = [['']*7 for n in range(75)] The list comprehension will execute ['']*7 each iteration, creating a new list instead of just creating new references to the same list. > Oh PS > > Is there a more elegant solution to > > if string == 'sun' or string == 'mon' or string == 'tue' or string == > 'wed' or string == 'thu' or string == 'fri' or string == 'sat': Try: if string in ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']: (Or perhaps look into using the datetime module, depending on how detailed your needs are.) Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] unhashable objects (unrelated to previous topic)
On Sun, 27 Mar 2005 18:08:41 -0500, Orri Ganel <[EMAIL PROTECTED]> wrote: > Hello all, > > I am attempting to implement a LinkedList in Python, and in doing so, > have created a Node class which represents the elements of the > LinkedList. However, since these Nodes have custom-defined __lt__(), > __gt__(), __le__(), __ge__(), __eq__(), and __ne__() methods, they > are, for some reason, unhashable. When I comment out these methods, > Python makes no complaint. But when they are present, 'TypeError: > unhashable instance' is raised when attempting to use a Node as a key > in a dictionary. When you don't define __eq__(), Python will use an object's ID as its hash value. However, the standard usage of hashes implies that objects which compare as equal should hash identically. This means that objects which define __eq__() and which are intended to be hashed need to define a __hash__() method. Be very careful if you're doing this with mutable objects, though -- you need to either hash by object identity or by object equality, and for mutable objects either choice will leave you breaking an implied promise. (Either a single object will not hash the same at different points in its life, or objects which are equal will not hash identically.) Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] If elif not working in comparison
On Mon, 28 Mar 2005 09:27:11 -0500, orbitz <[EMAIL PROTECTED]> wrote: > Floats are inherintly inprecise. So if thigns arn't working like you > expect don't be surprised if 0.15, 0.12, and 0.1 are closer to the same > number than you think. However, the imprecision of floats is in the 10-12 precision digit range. That is, it's precise up to about 0.01 (or slightly fewer decimal places if the integer part is large). Given the precision with which those constants are specified, I doubt that float imprecision will be an issue here, unless there's a *lot* of repeated operations, e.g. a loop with many (i.e. hundreds to thousands of) iterations. Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Launching a file browser
On Mon, 28 Mar 2005 18:53:39 -0800, Mike Hall <[EMAIL PROTECTED]> wrote: > I my case the gui will be comprised of html and javascript, talking to > python through system calls. I basically want to know if there's an > equivalent of the "webbrowser()" module (which launches my browser) for > file dialogs. This is what EasyDialogs should do, but does not. If you're using html and browser scripting for your GUI, then you'll probably need to use html and browser scripting for your file dialog too. A file dialog is just another GUI segment, so it should work the same as the rest of your GUI. Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Float precision untrustworthy~~~
On Mon, 28 Mar 2005 22:13:10 -0500, Jacob S. <[EMAIL PROTECTED]> wrote: > I've already deleted the recent thread-- > > But sometimes I agree with he who said that you can't trust floats at all. > > The scientific theory suggests that if an output is not what it should be, > then the hypothesis is untrue. > In this case, the hypothesis is the fact that float division should always > produce the same output as our decimal division used in common schools > today. Since that is not always true, then floats are not trustworthy~~~ > frankly, the mere fact that floats are difficult to check with equality has > bitten me more than anything I've met yet in python. The scientific method is also quite well aware of the limits of precision. *EVERY* tool that you use to make measurements has precision limits. In most of those cases, the imprecision due to measuring tools will overwhelmingly swamp the tiny bit of imprecision involved with floating-point arithmetic. It's also worth pointing out that most of the float imprecision isn't anything inherent in the floats themselves -- it's due to converting between binary and decimal representation. Just as a phrase that's translated from English into Russian and then back to English again can have its meaning shifted, translating between different numerical bases can create error -- but it's usually *much* less error than the natural language translations cause. Really, all this talk about floating-point imprecision is *way* overblown. It's important to be aware of it, yes, because in some cases it can be relevant... but it's a *long* way from making floats unusable or unreliable. > >>> 64**(1/3) == 4 > False > >>> 64**-3 == 4 > False > >>> a = 1/3 > >>> a > 0.1 Note that you'll have the same problems if you use a Decimal number type, because there's also an imprecision with Decimals. The problem is that you're expecting a digital variable with a limited discrete set of possible values to be equivalent to a rational number -- but no binary or decimal floating-point number can exactly represent 1/3. A Decimal approximation would have a 3 as the final digit rather than a 1, but there *would* be a final digit, and *that* is why this can't work. > Why not just implement decimal or some equivalent and > get rid of hidden, hard to debug headaches? Well, a Decimal type *has* been implemented... but it's just trading one set of headaches for another. What your code is apparently expecting is a Rational type, which has been discussed ad infinitum (and probably implemented several times, though not (yet) accepted into the standard library); Rationals have the problem, though, that any given operation may take an unpredictable amount of time to execute. Would you consider it an improvement if, instead of wondering why you're not getting an equality, you were wondering whether your machine had frozen? There's always a trade-off. It's important to be aware of the weaknesses of the tools that you use, but *every* tool has weaknesses, and it doesn't make sense to discard a tool just because you've learned what those weaknesses are. Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Launching a file browser
On Mar 31, 2005 2:14 PM, Mike Hall <[EMAIL PROTECTED]> wrote: > > >> It's been too long since I used Python on MacOSX, but IIRC you can't > >> just run a Python GUI program from the shell. Or something like > >> that...you should ask this one on the python-mac SIG mailing list: > >> http://www.python.org/sigs/pythonmac-sig/ > >> > >> Kent > > I'm unclear on why a command like webbrowser.open() will comfortably > launch your default web browser (in my case Safari), but something as > ubiquitous to an OS as a file browser has special needs to launch. At the OS level, these two actions are *completely* different. The webbrowser module launches an entirely separate program in its own independent process, where the "file browser" is opening a standard dialog inside of the current process and dependent upon the current process' message loop. (AFAIK, every GUI environment uses some sort of message/event loop...) I don't know Macs, but on Windows, the closest "file browser" parallel to what the webbrowser module is doing would be os.system("explorer.exe"), which launches a separate program in an independent process. However, if you're trying to get the results of the file selection back into your own app, you need to do the file browsing within your own process (or explicitly use some form of inter-process communication). In order to use a GUI file-browsing dialog, you need to follow all the rules for a GUI program. Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] random import errors?
On Apr 1, 2005 3:20 PM, Jay Loden <[EMAIL PROTECTED]> wrote: > I have a python script that runs on my webserver every fifteen minutes. It > has run for several months with absolutely no problems. Suddenly, yesterday > morning I got an email from cron with an import error for sre_constants (see > below) Since you're able to import these files manually, it's unlikely to be a problem with your Python installation. I'd suggest trying to figure out what changed between the day before yesterday and yesterday. I'm just guessing here, but I'd expect that this is probably related to either permissions or environment variables. Jeff Shannon ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] odd behavior within __init__
(Oops, forgot to change this to go to the list...) On 4/14/05, Orri Ganel <[EMAIL PROTECTED]> wrote: > On 4/14/05, Rich Krauter <[EMAIL PROTECTED]> wrote: > > On 4/14/05, Max Noel <[EMAIL PROTECTED]> wrote: > >Well, if you want b and a to refer to the same object, just use b = > > a. > > If you'll look at my code, you'll see that I *did* try that approach, > and it did not persist past __init__ for some reason: That's because you re-bound the local name 'self', but that doesn't affect anything outside the local namespace. Remember, __init__() returns None; the object has already been allocated before __init__() is called, and while __init__() can mutate the object it can't affect the reference that the interpreter has created. (Unless you resort to hacking the contents of the parent frame, but we won't get into that. You *don't* want to do this.) In this case, I agree that a factory is your best bet. Jeff Shannon > > class Node: > ... > def __init__(self, cargo=None, prev=None, next=None, nod=False): > """x.__init__(...) initializes x; see > x.__class__.__doc__ for signature""" > if not isinstance(cargo, Node) or nod: > self.cargo = cargo > self.prev = prev > self.next = next > else: > # > self = cargo ## see? > # > print id(self), id(cargo) > print self.cargo > > >>> a = Node(1) > >>> b = Node(a) > 12932600 12932600 > 1 > >>> id(b) > 12960632 > > -- > Email: singingxduck AT gmail DOT com > AIM: singingxduck > Programming Python for the fun of it. > ___ > Tutor maillist - Tutor@python.org > http://mail.python.org/mailman/listinfo/tutor > ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor