Re: [Tutor] using the loop function while another
On 10/10/12 02:14, eryksun wrote: another=input('Do you have another book to order for this student?', '\nEnter y for yes: ') Remove the comma, and this will parse correctly. Oops, yes good catch, don't know where that came from. another=input(''' Do you have another book to order for this student? Enter y for yes: ''') This retains the leading spaces. You can use textwrap.dedent() to remove them: I intended the spaces but didn't know about textwrap let alone dedent(). You learn something new every day! :-) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] ctypes question
Hi, I have a program that reads and writes files using ctypes. When I want it to read AND write (e.g. read a file, select some stuff and write that), the library returns a 'read-open' error. I think that the pointer to the file handle for read and write point to the same address. To test that hypothesis, I wrote the simplified code below. Problem is, that I can't make it work, let alone come up with a solution. ;-( How do I tell ctypes to use a particular chunck of memory, so read and write buffers do not mutually interfere? Maybe the 'offset' parameter of ctypes.byref? import ctypes import platform import os import tempfile # load libraries pf = platform.platform().lower() if pf.startswith(win): libc = ctypes.cdll.msvcrt fopen = libc._fdopen elif pf.startswith(lin): libc = ctypes.CDLL(libc.so.6) fopen = libc.fdopen elif pf.startswith(darwin): libc = ctypes.CDLL(libc.dylib) fopen = libc.fdopen else: raise NotImplementedError # create test data path = tempfile.gettempdir() os.chdir(path) fn = test.txt lines = 100 * (100 * * + os.linesep) with open(fn, wb) as f: f.write(lines) # read test data (code does NOT work) fh = fopen(ctypes.c_char_p(fn), rb) fhPtr = ctypes.byref(ctypes.c_int(fh)) buff = ctypes.create_string_buffer(lines) ret = libc.fread(buff, ctypes.c_int(1), ctypes.c_int(len(lines)), fhPtr) print buff.value # write test data (code does NOT work) fn = somefile.txt fh_out = fopen(ctypes.c_char_p(fn), wb) fh_outPtr = ctypes.byref(ctypes.c_int(fh_out)) buff = ctypes.create_string_buffer(lines) ret = libc.fwrite(buff, ctypes.c_int(1), ctypes.c_int(len(lines)), fh_outPtr) Thanks in advance! Regards, Albert-Jan ~~ All right, but apart from the sanitation, the medicine, education, wine, public order, irrigation, roads, a fresh water system, and public health, what have the Romans ever done for us? ~~ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] ctypes question
Albert-Jan Roskam wrote: I have a program that reads and writes files using ctypes. When I want it to read AND write (e.g. read a file, select some stuff and write that), the library returns a 'read-open' error. I think that the pointer to the file handle for read and write point to the same address. In C fopen() returns a FILE *, open() returns an int. If your library expects a file handle, i. e. an int you can open the file in Python f = open(filename, r+b) and pass f.fileno() to the library. To test that hypothesis, I wrote the simplified code below. Problem is, that I can't make it work, let alone come up with a solution. ;-( How do I tell ctypes to use a particular chunck of memory, so read and write buffers do not mutually interfere? Maybe the 'offset' parameter of ctypes.byref? I think you should turn to python-list instead of tutor with problems like this. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] ctypes question
On 10/10/12 11:02, Albert-Jan Roskam wrote: I have a program that reads and writes files using ctypes. Any particular reason why? That's not normally something I'd expect you to need ctypes for. Unless you just want to play with ctypes... When I want it to read AND write (e.g. read a file, select some stuff and write that), the library returns a 'read-open' error. Can we see the error messages please? I think that the pointer to the file handle for read and write point to the same address. To test that hypothesis, I wrote the simplified code below. Problem is, that I can't make it work Again, what exactly is going wrong. can't make it work is not too helpful, we need specific descriptions of what went wrong with any error messages. How do I tell ctypes to use a particular chunck of memory, so read and write buffers do not mutually interfere? In general you don't, you leave all that to the OS via the C libraries. But you do need to think about what you are doing with the file. You shouldn't open the same file simultaneously for read and write. If you do need to do both use the combined 'rw' mode - but be aware that getting simultaneous read/write behaviour right is hard! Maybe the 'offset' parameter of ctypes.byref? import ctypes import platform import os import tempfile # load libraries pf = platform.platform().lower() if pf.startswith(win): libc = ctypes.cdll.msvcrt fopen = libc._fdopen elif pf.startswith(lin): libc = ctypes.CDLL(libc.so.6) fopen = libc.fdopen elif pf.startswith(darwin): libc = ctypes.CDLL(libc.dylib) fopen = libc.fdopen else: raise NotImplementedError # create test data path = tempfile.gettempdir() os.chdir(path) fn = test.txt lines = 100 * (100 * * + os.linesep) with open(fn, wb) as f: f.write(lines) # read test data (code does NOT work) fh = fopen(ctypes.c_char_p(fn), rb) fhPtr = ctypes.byref(ctypes.c_int(fh)) buff = ctypes.create_string_buffer(lines) ret = libc.fread(buff, ctypes.c_int(1), ctypes.c_int(len(lines)), fhPtr) print buff.value # write test data (code does NOT work) fn = somefile.txt fh_out = fopen(ctypes.c_char_p(fn), wb) fh_outPtr = ctypes.byref(ctypes.c_int(fh_out)) buff = ctypes.create_string_buffer(lines) ret = libc.fwrite(buff, ctypes.c_int(1), ctypes.c_int(len(lines)), fh_outPtr) Again, what does NOT work? Does it work if you comment out one of the blocks? I don't use ctypes much and certainly not for file handling so can't be sure if the code is correct or not - maybe ask on a ctypes forum for that... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] ctypes question
On Wed, Oct 10, 2012 at 6:02 AM, Albert-Jan Roskam fo...@yahoo.com wrote: elif pf.startswith(lin): libc = ctypes.CDLL(libc.so.6) fopen = libc.fdopen fh = fopen(ctypes.c_char_p(fn), rb) fhPtr = ctypes.byref(ctypes.c_int(fh)) buff = ctypes.create_string_buffer(lines) ret = libc.fread(buff, ctypes.c_int(1), ctypes.c_int(len(lines)), fhPtr) print buff.value fdopen takes a file descriptor, not a filename. You're using it with a filename like fopen (and you even called it fopen). Also, the byref usage is incorrect. fopen() returns a pointer to a FILE. fread() needs the pointer, not a reference to the pointer. You're giving it the address of an int, but it expects to find a FILE. You can use c_void_p(fh), or set the argtypes. from ctypes import * import ctypes.util libc = cdll.LoadLibrary(ctypes.util.find_library('c')) fopen = libc.fopen fread = libc.fread fread.argtypes = [c_void_p, c_size_t, c_size_t, c_void_p] fh = fopen(spam.txt, rb) buf = create_string_buffer(128) fread(buf, 1, 128, fh) 5 buf.value 'spam\n' To use fdopen, you can get a fileno() from an open Python file object: f = open(spam.txt, rb) fdopen = libc.fdopen fh = fdopen(f.fileno(), rb) fread(buf, 1, 128, fh) 5 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] ctypes question
- Original Message - From: eryksun eryk...@gmail.com To: Albert-Jan Roskam fo...@yahoo.com Cc: Python Mailing List tutor@python.org Sent: Wednesday, October 10, 2012 1:40 PM Subject: Re: [Tutor] ctypes question On Wed, Oct 10, 2012 at 6:02 AM, Albert-Jan Roskam fo...@yahoo.com wrote: elif pf.startswith(lin): libc = ctypes.CDLL(libc.so.6) fopen = libc.fdopen fh = fopen(ctypes.c_char_p(fn), rb) fhPtr = ctypes.byref(ctypes.c_int(fh)) buff = ctypes.create_string_buffer(lines) ret = libc.fread(buff, ctypes.c_int(1), ctypes.c_int(len(lines)), fhPtr) print buff.value fdopen takes a file descriptor, not a filename. You're using it with a filename like fopen (and you even called it fopen). Also, the byref usage is incorrect. fopen() returns a pointer to a FILE. fread() needs the pointer, not a reference to the pointer. You're giving it the address of an int, but it expects to find a FILE. You can use c_void_p(fh), or set the argtypes. Aha, thanks. Yes, my total lack of knowledge of C speaks volumes here. from ctypes import * import ctypes.util libc = cdll.LoadLibrary(ctypes.util.find_library('c')) That's a nice little trick! fopen = libc.fopen fread = libc.fread fread.argtypes = [c_void_p, c_size_t, c_size_t, c_void_p] fh = fopen(spam.txt, rb) buf = create_string_buffer(128) fread(buf, 1, 128, fh) 5 buf.value 'spam\n' To use fdopen, you can get a fileno() from an open Python file object: f = open(spam.txt, rb) fdopen = libc.fdopen fh = fdopen(f.fileno(), rb) fread(buf, 1, 128, fh) 5 Very insightful. I'll modify my code an see if it might solve my original problem. At least I've learnt a lot now! Thanks all for replying!! ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] iterating over a changing list
I'm trying to iterate over a list of elements, and make changes to the list in front of the element I'm currently working with. I can update the list, but the 'for' doesn't see the new element. Here's the code: import string def add_element(items, point): items = items[:point+1][:] + [['new']] + items[point+1:] return items def main(): pass itmlst = [['a'],['b']] itmcntr = 0 for itm in itmlst: cmd = '' while True: cmd = raw_input('break, add, print:') if cmd == 'break': break elif cmd == 'add': itmlst = add_element(itmlst,itmcntr) elif cmd == 'print': print 'current item:', itm else: print 'invalid' itmcntr += 1 print 'finished with', itm, 'in', itmlst print len(itmlst), 'total items in list' If I provide the inputs: [print add print break print break] at the prompt, I get this output current item: ['a'] current item: ['a'] finished with ['a'] in [['a'], ['new'], ['b']] current item: ['b'] finished with ['b'] in [['a'], ['new'], ['b']] 3 total items in list The new element got added, but it wasn't used in the iteration over the list of items. Other than setting up a counter and calling len() each loop, is there some way to have the changing list recognized within the for loop? Thanks in advance for any help. Ed ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] What can I do if I'm banned from a website??
I've been scraping info from a website with a url program I wrote. But now I can't open their webpage, no matter which web browser I use. I think they've somehow blocked me. How can I get back in? Is it a temporary block? And can I get in with the same computer from a different wifi? ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] What can I do if I'm banned from a website??
On Wed, Oct 10, 2012 at 4:35 PM, Benjamin Fishbein bfishbei...@gmail.comwrote: I've been scraping info from a website with a url program I wrote. But now I can't open their webpage, no matter which web browser I use. I think they've somehow blocked me. How can I get back in? Is it a temporary block? And can I get in with the same computer from a different wifi? ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor A few thoughts: 1. Try using a proxy. 2. Ask the webadmin (nicely) to unban you 3. Use requests / urllib3 to se connection pooling 4. See if the site has an API designed for data extraction. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] What can I do if I'm banned from a website??
how could someone know enough to write their own web-scraping program and NOT know that this is not about python or how to get around this problem? ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] iterating over a changing list
On 10/10/2012 20:52, Ed Owens wrote: I'm trying to iterate over a list of elements, and make changes to the list in front of the element I'm currently working with. I can update the list, but the 'for' doesn't see the new element. Here's the code: import string def add_element(items, point): items = items[:point+1][:] + [['new']] + items[point+1:] return items def main(): pass itmlst = [['a'],['b']] itmcntr = 0 for itm in itmlst: cmd = '' while True: cmd = raw_input('break, add, print:') if cmd == 'break': break elif cmd == 'add': itmlst = add_element(itmlst,itmcntr) elif cmd == 'print': print 'current item:', itm else: print 'invalid' itmcntr += 1 print 'finished with', itm, 'in', itmlst print len(itmlst), 'total items in list' If I provide the inputs: [print add print break print break] at the prompt, I get this output current item: ['a'] current item: ['a'] finished with ['a'] in [['a'], ['new'], ['b']] current item: ['b'] finished with ['b'] in [['a'], ['new'], ['b']] 3 total items in list The new element got added, but it wasn't used in the iteration over the list of items. Other than setting up a counter and calling len() each loop, is there some way to have the changing list recognized within the for loop? Thanks in advance for any help. Ed ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor Usually handled by iterating over a copy of the list. for itm in itmlst[:]: -- Cheers. Mark Lawrence. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] What can I do if I'm banned from a website??
On 10/10/2012 21:35, Benjamin Fishbein wrote: I've been scraping info from a website with a url program I wrote. But now I can't open their webpage, no matter which web browser I use. I think they've somehow blocked me. How can I get back in? Is it a temporary block? And can I get in with the same computer from a different wifi? ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor Grovel? Bribery? Threaten violence? Don't break their Ts Cs in the first place? And what has this got to do with Python? -- Cheers. Mark Lawrence. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] What can I do if I'm banned from a website??
Hi On 10 October 2012 21:35, Benjamin Fishbein bfishbei...@gmail.com wrote: I've been scraping info from a website with a url program I wrote. But now I can't open their webpage, no matter which web browser I use. I think they've somehow blocked me. How can I get back in? Is it a temporary block? And can I get in with the same computer from a different wifi? Hard to know for certain what they've done, perhaps they've blocked your IP. You can try connecting from another IP and see if that works. 2 points: 1) If you're going to be scraping websites, you should always play nice with the web-server -- throttle your requests (put some random delay between them) so they don't hammer the web-server too hard. Not doing this will enrage any webmaster. He'll be very quick to figure out why his website's being hammered, from where (the IP) and then block you. You'd probably do the same if you ran a website and you noticed some particular IP hammering your site.. 2) You should ideally always respect websites wishes regarding bots and scraping. If they don't want automated bots to be scraping them then you should really not scrape that site. And if you're going to disregard their wishes and scrape it anyway (not recommended), then all bets are off and you'll have to fly under the radar and ensure that your scraping app looks as much like a browser as possible (probably using modified headers that looks like what a browser will send) and behaves as much like a human operator driving a browser as possible, or you'll find yourself blocked as you've experienced above. Walter ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] iterating over a changing list
On 10/10/2012 03:52 PM, Ed Owens wrote: I'm trying to iterate over a list of elements, and make changes to the list in front of the element I'm currently working with. I can update the list, but the 'for' doesn't see the new element. Here's the code: import string def add_element(items, point): items = items[:point+1][:] + [['new']] + items[point+1:] return items This function doesn't change its input object at all, it's just creates and returns a new one. def main(): pass itmlst = [['a'],['b']] itmcntr = 0 for itm in itmlst: cmd = '' while True: cmd = raw_input('break, add, print:') if cmd == 'break': break elif cmd == 'add': itmlst = add_element(itmlst,itmcntr) Now you've created a brand new list, and bound it to the itemlst variable, but you're still iterating over the original list. elif cmd == 'print': print 'current item:', itm else: print 'invalid' itmcntr += 1 print 'finished with', itm, 'in', itmlst print len(itmlst), 'total items in list' If I provide the inputs: [print add print break print break] at the prompt, I get this output current item: ['a'] current item: ['a'] finished with ['a'] in [['a'], ['new'], ['b']] current item: ['b'] finished with ['b'] in [['a'], ['new'], ['b']] 3 total items in list The new element got added, but it wasn't used in the iteration over the list of items. Other than setting up a counter and calling len() each loop, is there some way to have the changing list recognized within the for loop? Usually, people have the reverse problem, one of seeming to stutter on one of the items, or skipping one. And the cure for either of those is (as Mark tried to point out) to make a new list object to iterate over. if you're sure you want to insert items in the original list that you're looping on, then you need to change two places. One is the add_element() function needs to either use the insert() or an equivalent set of slices. use the insert() method, since it's easier. And don't bother returning the list, since you're not creating a new one. Convention is to either return a new object, or modify an object in place, but not both. The other place to change is the place where you call that function. It should NOT bind the variable to the return value, since it doesn't want a new list object. I haven't studied the rest of your code, as it didn't make much sense to me. But it's probably a simplified version of whatever you are trying to do, so that should be fine. -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] iterating over a changing list
On Wed, Oct 10, 2012 at 3:52 PM, Ed Owens eowens0...@gmx.com wrote: import string Why are you importing string? Most string functions one would need are methods of str/unicode. Sometimes string is still required, however. def add_element(items, point): items = items[:point+1][:] + [['new']] + items[point+1:] return items items[:point+1][:] creates a copy of part of the list with the slice [:point+1], and then it copies the copy with the slice [:]. Redundant operations aside, this is returning a new list object. That's not going to work since the loop iterator is bound to the original list. You can't rebind a listiterator in the middle of a for loop. Also, generally avoid mutating a list while iterating over it. listiterator is just incrementing an index, so modifying the size of the list can produce nonsense (e.g. if you remove the current item, the next item will be skipped). Instead, create an empty list and append() to it. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] What can I do if I'm banned from a website??
On 11/10/12 07:35, Benjamin Fishbein wrote: I've been scraping info from a website with a url program I wrote. But now I can't open their webpage, no matter which web browser I use. I think they've somehow blocked me. How can I get back in? Is it a temporary block? How the hell would we know??? Ask the people running the web site. If you have been breaking the terms and conditions of the web site, you could have broken the law (computer trespass). I don't say this because I approve of or agree with the law, but when you scrape websites with anything other than a browser, that's the chance you take. And can I get in with the same computer from a different wifi? *rolls eyes* You've been blocked once. You want to get blocked again? A lot of this depends on what the data is, why it is put on the web in the first place, and what you intend doing with it. Wait a week and see if the block is undone. Then: * If the web site gives you an official API for fetching data, USE IT. * If not, keep to their web site TC. If the TC allows scraping under conditions (usually something on the lines of limiting how fast you can scrape, or at what times), OBEY THOSE CONDITIONS and don't be selfish. * If you think the webmaster will be reasonable, ask permission first. (I don't recommend that you volunteer the information that you were already blocked once.) If he's not a dick, he'll probably say yes, under conditions (again, usually to do with time and speed). * If you insist in disregarding their TC, don't be a dick about it. Always be an ethical scraper. If the police come knocking, at least you can say that you tried to avoid any harm from your actions. It could make the difference between jail and a good behaviour bond. - Make sure you download slowly: pause for at least a few seconds between each download, or even a minute or three. - Limit the rate that you download: you might be on high speed ADSL2, but the faster you slurp files from the website, the less bandwidth they have for others. - Use a cache so you aren't hitting the website again and again for the same files. - Obey robots.txt. Consider using a random pause between (say) 0 and 90 seconds between downloads to to more accurately mimic a human using a browser. Also consider changing your user-agent. Ethical scraping suggests putting your contact details in the user-agent string. Defensive scraping suggests mimicking Internet Explorer as much as possible. More about ethical scraping: http://stackoverflow.com/questions/4384493/how-can-i-ethically-and-legally-scrape-data-from-a-public-web-site -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why difference between printing string typing its object reference at the prompt?
On Tue, Oct 9, 2012 at 4:29 AM, eryksun eryk...@gmail.com wrote: snip Python 3 lets you use any Unicode letter as an identifier, including letter modifiers (Lm) and number letters (Nl). For example: aꘌꘌb = True aꘌꘌb True Ⅰ, Ⅱ, Ⅲ, Ⅳ, Ⅴ = range(1, 6) Ⅰ, Ⅱ, Ⅲ, Ⅳ, Ⅴ (1, 2, 3, 4, 5) Is doing this considered good programming practice? I recall there was a recent discussion about using the actual characters in formulas instead of descriptive names, where this would make more sense to people knowledgeable in the field using the formulas; however, descriptive names might be better for those who don't have that specialty knowledge. Is there a Python community consensus on how and when it is appropriate (if ever) to use Unicode characters as identifiers? A potential gotcha in Unicode is the design choice to have both [C]omposed and [D]ecomposed forms of characters. For example: from unicodedata import name, normalize s1 = ü name(s1) 'LATIN SMALL LETTER U WITH DIAERESIS' s2 = normalize(NFD, s1) list(map(name, s2)) ['LATIN SMALL LETTER U', 'COMBINING DIAERESIS'] These combine as one glyph when printed: print(s2) ü Different forms of the 'same' character won't compare as equal unless you first normalize them to the same form: s1 == s2 False normalize(NFC, s1) == normalize(NFC, s2) True This looks to make alphabetical sorting potentially much more complex. I will have to give this some thought once I know more. I don't see a mention of byte strings mentioned in the index of my text. Are these just the ASCII character set? After seeing your explanation below, I was able to find the relevant material in my book. It was under bytes type and bytearray type. For some reason these categories did not click in my head as what Steve was addressing. A bytes object (and its mutable cousin bytearray) is a sequence of numbers, each in the range of a byte (0-255). bytes literals start with b, such as b'spam' and can only use ASCII characters, as does the repr of bytes. Slicing returns a new bytes object, but an index or iteration returns integer values: b'spam'[:3] b'spa' b'spam'[0] 115 list(b'spam') [115, 112, 97, 109] bytes have string methods as a convenience, such as find, split, and partition. They also have the method decode(), which uses a specified encoding such as utf-8 to create a string from an encoded bytes sequence. What is the intended use of byte types? Thanks! This continues to be quite informative and this thread is greatly helping me to make better sense of the information that I am self-studying. -- Cheers! boB ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why difference between printing string typing its object reference at the prompt?
On 11/10/12 12:23, boB Stepp wrote: On Tue, Oct 9, 2012 at 4:29 AM, eryksuneryk...@gmail.com wrote: snip Python 3 lets you use any Unicode letter as an identifier, including letter modifiers (Lm) and number letters (Nl). For example: aꘌꘌb = True aꘌꘌb True Ⅰ, Ⅱ, Ⅲ, Ⅳ, Ⅴ = range(1, 6) Ⅰ, Ⅱ, Ⅲ, Ⅳ, Ⅴ (1, 2, 3, 4, 5) Is doing this considered good programming practice? Not really, but it depends who is doing it and why. If you have a piece of code that is only going to be maintained by people speaking French, with French keyboards, then why not use French words for identifiers? That includes those French letters with accents. Python 3 lets you do so. Silly bits of code like Ⅳ = 4 (or worse, Ⅳ = 9) should be avoided because they are silly, not because they are illegal. That's about the same as using: eine, zwei, drei, vier, fünf = range(1, 6) in code intended to be read by English speakers, only even harder to type. Remember that programmers *discourage* most misspellings of words (with a few exceptions, usually abbreviations): number_of_pages = 42 is preferred to: nombar_off_paiges = 42 But for non-English speakers, most languages *force* them to either write code in Foreign (foreign *to them*), or to misspell words. Allowing Unicode identifiers means that they can write in their native tongue, using correct spelling, *if they so choose*. Of course, if you want your code to be readable world-wide, stick to English :) -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] iterating over a changing list
On 11/10/12 08:49, eryksun wrote: Also, generally avoid mutating a list while iterating over it. listiterator is just incrementing an index, so modifying the size of the list can produce nonsense (e.g. if you remove the current item, the next item will be skipped). Instead, create an empty list and append() to it. If you absolutely have to modify the list you are iterating over, iterate over it backwards: # this doesn't work correctly for i in range(len(mylist)): x = mylist[i] if x 0: del mylist[i] # this does for i in range(len(mylist)-1, -1, -1): x = mylist[i] if x 0: del mylist[i] But really, don't do that either. Iterate over a copy, or make a new list with the items you want. It's faster and easier. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor