Re: [Tutor] functions--how long is too long?
Che M pine...@hotmail.com wrote I have some functions that seem kind of long to me. One of them, with I realize I can and should refactor parts that are used in other places in the code, but I don't there are that many in some of these. Is there a better way to think about organizing this? The length as such is not the critical factor, its the maintainability and readability. Can you function be easily understood by another programmer? Can you make changes to the function without changing the interface (which implies changes elsewhere in your code) Where you have a lot of if statements you might benefit from using a dictionary of functions or a function which returns a function. But there may be good reasons to keep the if statements too. Sorry, but a generalised question can only get a generalised answer. 57 lines of active code is big but not ridiculous. Over 100 liones I would be looking closely at breaking it up just for readability. Remember the old adage that a function should ideally fit on a single editor screen (or sheet of printout) - when I started that meant 25-60 lines was the range, now you can go up to 60-100 lines if needs be... -- Alan Gauld 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] functions--how long is too long?
Luke Paireepinart rabidpoob...@gmail.com dixit: I'd say my personal hard-limit for functions before I start refactoring is probably around 150-200 lines. But it's rare that functions get that long anyway. ! Aside questions of personal style taste, _I_ could not hold such long funcs. Far too much to manage for my head, about unmaintainable for me. My common limit is about one editor screen (~ 35 lines), comments included, which reveals not only practicle, but also about what my head is able to cope with at once. And my programming style rather leans toward clarity (-- low code density), meaning that 1 line of a smart coder may map to 2 or 3 of mine. An absolute limit would be about 2 screens. To sum up: 150 lines by luke * 2 (density) * 2 (comments) = 600 lines by myself ... compared to my ~ 50 lines medium limit means Luke is a ~ 12 times smarter coder than I am! ;-) This is a new evidence that coding efficiency is more a question of coder quality than anything else... Denis la vita e estrany http://spir.wikidot.com/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] functions--how long is too long?
On 12/8/2009 8:27 PM, Alan Gauld wrote: Remember the old adage that a function should ideally fit on a single editor screen (or sheet of printout) - when I started that meant 25-60 lines was the range, now you can go up to 60-100 lines if needs be... I disagree. I keep my text editor not maximized so I can have multiple editors open (or multiple splits when using (g)vim); a 100-lines function would take the all the screen and doesn't fit in one window. I generally would consider something above ~50 lines as very large. A large screen is better utilized for multiple windows rather than for larger functions. While you should not refactor just for the sake of keeping line-counts, perhaps you should try the small editor approach. Keep your editor unmaximized, for around 20 lines, around half a screen. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] loops
Richard Hultgren wrote: a = 0 b = 1 count = 0 max_count = 20 while count max_count: count = count + 1 # we need to keep track of a since we change it old_a = a# especially here old_b = b a = old_b b = old_a + old_b # Notice that the , at the end of a print statement keeps it # from switching to a new line print old_a, What's your question or comment? If you're just looking for a challenge, I'll point out that the same result could be gotten with 4 lines of Python. DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] loops
On 12/8/2009 9:39 PM, Dave Angel wrote: Richard Hultgren wrote: a = 0 b = 1 count = 0 max_count = 20 while count max_count: count = count + 1 # we need to keep track of a since we change it old_a = a # especially here old_b = b a = old_b b = old_a + old_b # Notice that the , at the end of a print statement keeps it # from switching to a new line print old_a, What's your question or comment? If you're just looking for a challenge, I'll point out that the same result could be gotten with 4 lines of Python. you lose, 1 line is all it takes for me: print 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Moving off topic: WAS Re: functions--how long is too long?
This is a new evidence that coding efficiency is more a question of coder quality than anything else... Don't know about new, The book Peopleware was highlighting that fact 20 years ago! It also showed the type of environment that maximised the productivity of good programmers - sadly, most of that is still ignored in businesses today. But the real challenge is how to raise the standard of the average programmer to narrow the gap between the best and the norm. Higher level languages like Python are one way to do that. -- Alan Gauld 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] loops
Lie Ryan lie.1...@gmail.com dixit: On 12/8/2009 9:39 PM, Dave Angel wrote: Richard Hultgren wrote: a = 0 b = 1 count = 0 max_count = 20 while count max_count: count = count + 1 # we need to keep track of a since we change it old_a = a # especially here old_b = b a = old_b b = old_a + old_b # Notice that the , at the end of a print statement keeps it # from switching to a new line print old_a, What's your question or comment? If you're just looking for a challenge, I'll point out that the same result could be gotten with 4 lines of Python. you lose, 1 line is all it takes for me: print 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 you lose, I don't even need a one-liner python prog to write a text into whatever stdout may be -- except if remote ;-) Denis la vita e estrany http://spir.wikidot.com/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] functions--how long is too long?
Lie Ryan lie.1...@gmail.com wrote editor screen (or sheet of printout) - when I started that meant 25-60 lines was the range, now you can go up to 60-100 lines if needs be... I disagree. I keep my text editor not maximized so I can have multiple editors open (or multiple splits when using (g)vim); a 100-lines function would take the all the screen and doesn't fit in one window. Personally I tend to have about 35-40 lines available in my editor, but if needs be - which is what I said, an exceptional case, not normal - I can get 100 lines on screen(*) using a small font. Which means I can at a pinch see a full 100 line function on screen. I don't recommend it, but it can be done! (*)Using a 24inch monitor set to 1600x1200 resolution While you should not refactor just for the sake of keeping line-counts, perhaps you should try the small editor approach. Keep your editor unmaximized, for around 20 lines, around half a screen. Hmm, I spent the first 10 years of my programming life using VT100 terminals with 24 lines max(*), I really don't want to go back there thanks! :-) (*)Actually I'm amazed how many Linux users with X Windows still bring up the default sized console/xterm with 24 lines. One of the first things I do on any new Linux install is set the xdefaults for xterm to 40 lines! (And change the colours!) -- Alan Gauld 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] mod_python authentication
On Mo, 2009-12-07 at 23:10 -0500, Marc wrote: While I agree with the cookie (as long as it has a short expiration), another way to do this is by using expiring tokenization (credentials+ some unique data for the transaction) in the URL header (see section 14.8 at http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html). Tokenization substitutes some random string for confidential data (such as credentials). This is essentially what I said about passing variables in the URL. The important thing still is information hiding, though: you don't want the user to have any clue what those variables mean so they can't modify them too easily. This is also why you should never expose critical variables (e.g. user ID) to possible modification. The payment card industry uses this in the form of an authorization code for card transactions. Add to the data represented by the token some unique data (maybe a random number or some data from the last transaction - it doesn't matter as the token does not expose the data in any way) for each http transaction so you have unique token in each header and you can get an essentially stateful session with a method of checking authentication that has some spoof protection built in. The problem to keep in mind, though, is that your users may be multi-tabbing, i.e. keeping several pages open at the same time. Don't ever rely on a linear experience unless you're dealing with something inherently linear like a survey (though in that case you should probably try to keep it to one page, possibly updated with JavaScript requests if the form doesn't look too friendly on one page) or a check-out process. Wrap it all in SSL/TLS and then you've got something. Granted, this requires some serious server side work, and is probably not a good beginner exercise, but if this level is what you need I have never coded anything like this in Python, but I can see abstractly how it could be done (I'm a novice with Python). If you're bored, you can read http://www.shift4.com/pdf/TokenizationWhitePaper.pdf especially sec1:7. I agree that if you're going for high security/safety tokenization can help, but for most intents and purposes it really isn't necessary. The idea is to avoid re-submission (especially of counter-intuitively side-effect non-free actions like GET requests) and make each action uniquely identifiable, if I understand the method correctly. This is normally only necessary for things like checkouts (keep track of the order ID and make sure the customer can't accidentally place an order twice e.g. by double-clicking the submit button or re-clicking it if the connection hangs) or form submission that affects the server state (e.g. posting a message to a forum, sending an e-mail, ...). SSL/TLS is also usually overkill for most purposes. Certificates provided by many non-commercial authorities will still trigger security warnings in most browsers, so the only way to get one that isn't counter-productive (i.e. diminishes trust rather than increasing it -- dodgy certificates are still valid certificates) is to shell out the big money -- and unless you're into serious business (i.e. anything big enough to justify the expenses), you probably can't be arsed. Cheers, Alan Plum ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] functions--how long is too long?
On Tue, Dec 8, 2009 at 4:17 AM, spir denis.s...@free.fr wrote: Luke Paireepinart rabidpoob...@gmail.com dixit: I'd say my personal hard-limit for functions before I start refactoring is probably around 150-200 lines. But it's rare that functions get that long anyway. ! Aside questions of personal style taste, _I_ could not hold such long funcs. Far too much to manage for my head, about unmaintainable for me. My common limit is about one editor screen (~ 35 lines), comments included, which reveals not only practicle, but also about what my head is able to cope with at once. And my programming style rather leans toward clarity (-- low code density), meaning that 1 line of a smart coder may map to 2 or 3 of mine. An absolute limit would be about 2 screens. To sum up: 150 lines by luke * 2 (density) * 2 (comments) = 600 lines by myself The 150-200 lines was including comments and everything else. And I just meant that is the point where I would be forced to refactor. For shorter functions that are unclear I would refactor before I got to that many lines. But like I said, most functions I write just tend to be naturally much shorter than that anyway. I was just trying to point out that there is a point where you are forced to refactor just because of the size, but before that point, refactoring may actually make your functions more confusing and harder to follow. It's a situational thing, which is why I asked for code originally. -Luke ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] loops
2009/12/8 spir denis.s...@free.fr: Lie Ryan lie.1...@gmail.com dixit: On 12/8/2009 9:39 PM, Dave Angel wrote: Richard Hultgren wrote: a = 0 b = 1 count = 0 max_count = 20 while count max_count: count = count + 1 # we need to keep track of a since we change it old_a = a # especially here old_b = b a = old_b b = old_a + old_b # Notice that the , at the end of a print statement keeps it # from switching to a new line print old_a, What's your question or comment? If you're just looking for a challenge, I'll point out that the same result could be gotten with 4 lines of Python. you lose, 1 line is all it takes for me: print 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 you lose, I don't even need a one-liner python prog to write a text into whatever stdout may be -- except if remote ;-) Denis la vita e estrany http://spir.wikidot.com/ ___ Tutor maillist - tu...@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor This, of course is a rather dirty, implementation (and probably version) specific hack, but I can /calculate/ the sequence, using just one line: print .join(str(i) for i in [x if x2 else (locals()['_[1]'][-1]+locals()['_[1]'][-2]) for x in xrange(20)]) 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 (CPython 2.6, on osx10.6) It's slightly more typing than the plain string, but extend it to about 30 entries, and I think I win? Note to OP: don't _ever_ do it this way in a serious project. -- Rich Roadie Rich Lovely There are 10 types of people in the world: those who know binary, those who do not, and those who are off by one. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Fw: loops
- Forwarded Message From: Richard Hultgren hultgren1...@yahoo.com To: tutor@python.org Sent: Mon, December 7, 2009 2:53:40 PM Subject: loops I'm quite new but determined. Can you explain to me, step by step, what is going on in the computer in this loop. I hope I am not being too dumb! a = 0 b = 1 count = 0 max_count = 20 while count max_count: count = count + 1 # we need to keep track of a since we change it old_a = a# especially here old_b = b a = old_b b = old_a + old_b # Notice that the , at the end of a print statement keeps it # from switching to a new line print old_a, ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Fw: loops
- Forwarded Message From: Richard Hultgren hultgren1...@yahoo.com To: tutor@python.org Sent: Mon, December 7, 2009 2:53:40 PM Subject: loops I'm quite new but determined. Can you explain to me, step by step, what is going on in the computer in this loop. I hope I am not being too dumb! Hmm...that still seems like quite a broad question. Can you be more specific about which portion you find confusing or unclear? If not, you might do better by starting with a general programming text. The top one is a list of texts for beginning programmers, followed by a few specific links to online texts: http://wiki.python.org/moin/BeginnersGuide/NonProgrammers http://www.freenetpages.co.uk/hp/alan.gauld/ http://swaroopch.com/notes/Python HTH, Serdar ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] File renaming using os.rename problem
I can't find anything on this error I am getting when renaming some files. I'm pulling info from a csv file and parsing it to build new file names. Any pointers appreciated Roy My code: # RENAME FILES using META file - new name = [place]_[state]_[sku].tif import re, os, csv # DEFINE _meta_file = C:\\Documents and Settings\\rhinkelman\\My Documents\\My Dropbox\\Public\\Python code examples\\topo_meta_TEST.csv _files_to_mod = Dc2\\inetpub2\\Image Production\\missing_topo\\topo sz3\\test _del_space = re.compile( ' ' ) #OPEN file containing TOPO meta, DEFINE OLD AND NEW NAMES _meta = csv.reader(open(_meta_file, r)) for _row in _meta: if _row[0] == NAME: continue print '|'.join(_row) # test old_name = _row[4].lstrip('o') + .pdf new_name = _row[0] + _ + _row[1] + _ + _row[4] + .pdf new_name = _del_space.sub( '_', new_name ) print old_name + - + new_name # test # OPEN DIR OF FILES TO BE RENAMED AND LOOK FOR NAME, RENAME AND CONTINUE for fname in os.listdir(_files_to_mod): if fname == old_name: print fname # test os.rename(fname, new_name) break else: continue AND the error Aberdeen|CA|36.875|-118.250|o36118h3 36118h3.pdf - Aberdeen_CA_o36118h3.pdf 36118h3.pdf Traceback (most recent call last): File C:\Documents and Settings\rhinkelman\My Documents\My Dropbox\Public\Python code examples\Rename_topo_files.py, line 25, in module os.rename(fname, new_name) WindowsError: [Error 2] The system cannot find the file specified ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] File renaming using os.rename problem
Roy Hinkelman royh...@gmail.com dixit: I can't find anything on this error I am getting when renaming some files. I'm pulling info from a csv file and parsing it to build new file names. Any pointers appreciated Roy My code: # RENAME FILES using META file - new name = [place]_[state]_[sku].tif import re, os, csv # DEFINE _meta_file = C:\\Documents and Settings\\rhinkelman\\My Documents\\My Dropbox\\Public\\Python code examples\\topo_meta_TEST.csv _files_to_mod = Dc2\\inetpub2\\Image Production\\missing_topo\\topo sz3\\test _del_space = re.compile( ' ' ) #OPEN file containing TOPO meta, DEFINE OLD AND NEW NAMES _meta = csv.reader(open(_meta_file, r)) for _row in _meta: if _row[0] == NAME: continue print '|'.join(_row) # test old_name = _row[4].lstrip('o') + .pdf new_name = _row[0] + _ + _row[1] + _ + _row[4] + .pdf new_name = _del_space.sub( '_', new_name ) print old_name + - + new_name # test # OPEN DIR OF FILES TO BE RENAMED AND LOOK FOR NAME, RENAME AND CONTINUE for fname in os.listdir(_files_to_mod): if fname == old_name: print fname # test os.rename(fname, new_name) break else: continue AND the error Aberdeen|CA|36.875|-118.250|o36118h3 36118h3.pdf - Aberdeen_CA_o36118h3.pdf 36118h3.pdf Traceback (most recent call last): File C:\Documents and Settings\rhinkelman\My Documents\My Dropbox\Public\Python code examples\Rename_topo_files.py, line 25, in module os.rename(fname, new_name) WindowsError: [Error 2] The system cannot find the file specified Why don't you simply print out fname? This should point you to the error. Denis la vita e estrany http://spir.wikidot.com/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] File renaming using os.rename problem (spir)
Why don't you simply print out fname? This should point you to the error. Denis I did here: if fname == old_name: print fname # test and it looks correct. On an WinXP, should I use shutil instead? Roy ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] File renaming using os.rename problem
spir wrote: Roy Hinkelman royh...@gmail.com dixit: I can't find anything on this error I am getting when renaming some files. I'm pulling info from a csv file and parsing it to build new file names. Any pointers appreciated Roy My code: # RENAME FILES using META file - new name = [place]_[state]_[sku].tif import re, os, csv # DEFINE _meta_file = C:\\Documents and Settings\\rhinkelman\\My Documents\\My Dropbox\\Public\\Python code examples\\topo_meta_TEST.csv _files_to_mod = Dc2\\inetpub2\\Image Production\\missing_topo\\topo sz3\\test _del_space = re.compile( ' ' ) #OPEN file containing TOPO meta, DEFINE OLD AND NEW NAMES _meta = csv.reader(open(_meta_file, r)) for _row in _meta: if _row[0] == NAME: continue print '|'.join(_row) # test old_name = _row[4].lstrip('o') + .pdf new_name = _row[0] + _ + _row[1] + _ + _row[4] + .pdf new_name = _del_space.sub( '_', new_name ) print old_name + - + new_name # test # OPEN DIR OF FILES TO BE RENAMED AND LOOK FOR NAME, RENAME AND CONTINUE for fname in os.listdir(_files_to_mod): if fname == old_name: print fname # test os.rename(fname, new_name) break else: continue AND the error Aberdeen|CA|36.875|-118.250|o36118h3 36118h3.pdf - Aberdeen_CA_o36118h3.pdf 36118h3.pdf Traceback (most recent call last): File C:\Documents and Settings\rhinkelman\My Documents\My Dropbox\Public\Python code examples\Rename_topo_files.py, line 25, in module os.rename(fname, new_name) WindowsError: [Error 2] The system cannot find the file specified Why don't you simply print out fname? This should point you to the error. Denis la vita e estrany http://spir.wikidot.com/ Actually he did, in the line immediately before the os.rename() call. See the line just before the traceback 36118h3.pdf Roy, your problem is that you've confirmed that the file 36118h3.pdf exists in the test directory (specified in _files_to_mod), but you're trying to rename a different file in the current directory. Your call to os.rename() needs to have a full path to the actual file. See os.path.join() to build such. DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Fw: loops
You should probably read some of the links sent to you earlier but here is a stab at an explanation. Richard Hultgren wrote on 12/08/2009 10:36:08 AM: - Forwarded Message From: Richard Hultgren hultgren1...@yahoo.com To: tutor@python.org Sent: Mon, December 7, 2009 2:53:40 PM Subject: loops I'm quite new but determined. Can you explain to me, step by step, what is going on in the computer in this loop. I hope I am not being too dumb! a = 0 b = 1 count = 0 max_count = 20 The above steps are initialization of your variables. 'a' points to the value 0, 'b' points to 1, etc. Since the values of the variables are used within the loop we need to give it somewhere to start, otherwise we will get an error. while count max_count: The while loop will continue until 'count max_count' evaluates to False (20 loops, due to line below) the loop is defined as everything that is indented below this line. count = count + 1 Increase the value of count by one each loop iteration, otherwise the statement 'count max_count' will never change value, and the loop will never end. # we need to keep track of a since we change it old_a = a# especially here old_b = b Keep the old values of the variables since we want to add them together for the new value of b and will change the values in the next steps. a = old_b b = old_a + old_b reassign 'a' to the value of 'old_b'. If we didn't save the value of 'a' into 'old_a' above we wouldn't know what it was anymore. reassign 'b' to the sum of 'old_a' and 'old_b' # Notice that the , at the end of a print statement keeps it # from switching to a new line print old_a, prints the value of old_a followed by a space. Without the comma at the end the print statement each loop would print on a new line. The best way to follow what is happening is to trace the variables through the program. you would get a table that loops something like : max_count count a b old_a old_b countmax_count OUTPUT 20 0 0 1 no ValueNo Value T No output yet 20 1 1 1 0 1 T 0 20 2 1 2 1 1 T 0 1 20 3 2 3 1 2 T 0 1 1 20 4 3 5 2 3 T 0 1 1 2 20 5 5 8 3 5 T 0 1 1 2 3 20 6 8 13 5 8 T 0 1 1 2 3 5 . . . 20 19 2584676541812584T 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 20 20 2584676541812584F 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 (You might want to check the last two rows, not guaranteeing the values are right) In the last row countmax_count is False the loop won't run and therefore nothing will change. Hope this helps some, but would recommend you try following some of the tutorials online for beginning programming to help explain some of the concepts, feel free to ask here whenever you get confused. Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] File renaming using os.rename problem (spir)
I got it. Switched to shutil and made to paths complete paths. The added benefit is that it didn't trash the original file. shutil.copy2(_files_to_mod + \\ + fname, _files_to_mod + \\ + new_name) Thanks. -- Forwarded message -- From: Roy Hinkelman royh...@gmail.com Date: Tue, Dec 8, 2009 at 12:27 PM Subject: Re: File renaming using os.rename problem (spir) To: tutor@python.org Why don't you simply print out fname? This should point you to the error. Denis I did here: if fname == old_name: print fname # test and it looks correct. On an WinXP, should I use shutil instead? Roy ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] functions--how long is too long?
On 12/8/2009 10:43 PM, Alan Gauld wrote: While you should not refactor just for the sake of keeping line-counts, perhaps you should try the small editor approach. Keep your editor unmaximized, for around 20 lines, around half a screen. Hmm, I spent the first 10 years of my programming life using VT100 terminals with 24 lines max(*), I really don't want to go back there thanks! :-) Whoaa... who puts 20 there!! A doppelganger of me? Ignore that. Half a screenful would be more than 20 lines even with laptop widescreen. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] duplication in unit tests
On Tue, Dec 8, 2009 at 6:02 PM, Serdar Tumgoren zstumgo...@gmail.com wrote: As part of my program, I'm planning to create objects that perform some initial data clean-up and then parse and database the cleaned data. Currently I'm expecting to have a FileCleaner and Parser classes. Using the TDD approach, I've so far come up with the below: class FileCleaner(object): def __init__(self, datastring): self.source = datastring def convertEmDashes(self): Convert unicode emdashes to minus signs self.datastring = self.source.replace(u'\u2014','-') def splitLines(self): Generate and store a list of cleaned, non-empty lines self.data = [x.strip() for x in self.datastring.strip().split('\n') if x.strip()] My confusion involves the test code for the above class and its methods. The only way I can get splitLines to pass its unit test is by first calling the convertEmDashes method, and then splitLines. class TestFileCleaner(unittest.TestCase): def setUp(self): self.sourcestring = uThis line has an em\u2014dash.\n So does this \u2014\n. self.cleaner = FileCleaner(self.sourcestring) def test_convertEmDashes(self): convertEmDashes should remove minus signs from datastring attribute teststring = self.sourcestring.replace(u'\u2014','-') self.cleaner.convertEmDashes() self.assertEqual(teststring, self.cleaner.datastring) def test_splitLines(self): splitLines should create a list of cleaned lines teststring = self.sourcestring.replace(u'\u2014','-') data = [x.strip() for x in teststring.strip().split('\n') if x.strip()] self.cleaner.convertEmDashes() self.cleaner.splitLines() self.assertEqual(data, self.cleaner.data) Basically, I'm duplicating the steps from the first test method in the second test method (and this duplication will accrue as I add more cleaning methods). I see a few problems with this. You are confused about what splitLines() does. It does not create a list of cleaned lines, it just splits the lines. Because of your confusion about splitLines(), your test is not just testing splitLines(), it is testing convertEmDashes() and splitLines(). That is why you have code duplication. test_splitLines() could look like this: def test_splitLines(self): splitLines should create a list of split lines teststring = self.sourcestring data = [x.strip() for x in teststring.strip().split('\n') if x.strip()] self.cleaner.splitLines() self.assertEqual(data, self.cleaner.data) Your tests are not very good. They don't really test anything because they use the same code that you are trying to test. What if str.replace() or split() or strip() does not work the way you expect? Your tests would not discover this. You should just hard-code the expected result strings. I would write test_splitLines() like this: def test_splitLines(self): splitLines should create a list of split lines data = [uThisline has an em\u2014dash., uSo does this \u2014, u.] self.cleaner.splitLines() self.assertEqual(data, self.cleaner.data) You probably don't want to hard-code the source string in the setup method. Typically you want to test a function with multiple inputs so you can check its behaviour with typical values, edge cases and invalid input. For example test_splitLines() doesn't verify that splitLines() removes blank lines; that would be a good test case. You might make a list of pairs of (input value, expected result) and pass each one to splitLines(). So my questions -- Am I misunderstanding how to properly write unit tests for this case? Or perhaps I've structured my program incorrectly, and that's what this duplication reveals? I suspected, for instance, that perhaps I should group these methods (convertEmDashes, splitLines, etc.) into a single larger function or method. Yes, your tests are revealing a problem with the structure. You should probably have a single process() method that does all the cleanup methods and the split. Then you could also have a test for this. There is really no need for a class here. You could write separate functions for each cleanup and for the split, then another function that puts them all together. This would be easier to test, too. Kent ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] File renaming using os.rename problem (spir)
On Tue, 2009-12-08 at 14:55 -0800, Roy Hinkelman wrote: shutil.copy2(_files_to_mod + \\ + fname, _files_to_mod + \\ + new_name) You can make os.path.join sort out the directory seprator for you. It will add a / under linux and \ under windows. os.path.join('Testing dir','oldname dir','filename') 'Testing dir/oldname dir/filename' So the code above can be like, import os oldname = os.path.join(_files_to_mod, fname) newname = os.path.join(_files_to_mod, new_name) shutil.copy2(oldname, newname) Not sure if it is a concern in your case but as far as I know shutil.copy2 will overwrite any existing files with the new_name without warning. Have a look at [1] for a great explanation on os.path. Greets Sander [1] http://blog.doughellmann.com/2008/01/pymotw-ospath.html ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] loops
On 12/9/2009 3:18 AM, Rich Lovely wrote: 2009/12/8 spirdenis.s...@free.fr: This, of course is a rather dirty, implementation (and probably version) specific hack, but I can /calculate/ the sequence, using just one line: print .join(str(i) for i in [x if x2 else (locals()['_[1]'][-1]+locals()['_[1]'][-2]) for x in xrange(20)]) 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 (CPython 2.6, on osx10.6) the best one-liner golf score for now (83 chars, requires python3), quite obfuscated: (lambda*n:n[0](*n))(lambda f,n,a=0,b=1:n0 or print(a,end=' ')or f(f,n-1,b,a+b),19) and though not a pure one-liner, the most straightforward method is just a char away (84 chars, python2): a=[0,1];[a.append(sum(a[-2:]))for x in range(3)][0];print' '.join(str(x)for x in a) if you don't require one-liner you can make it even shorter (81 chars, '\n'==1char, requires python2) a=[0,1] for x in range(18):a.append(sum(a[-2:])) print' '.join(str(x) for x in a) All codes tested on command-line with -c argument (i.e. the shell's default repr()-ing of expressions is ignored), result must be printed to screen as numbers separated by space (printing with list repr, e.g. [0, 1, ...] is not acceptable). Trailing space is ignored. It's slightly more typing than the plain string, but extend it to about 30 entries, and I think I win? Think again... Note to OP: don't _ever_ do it this way in a serious project. OP: In a real project, readability counts. Inglfng,spcecnts. PS: Perl fans might complain that their favorite pastime is stolen ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Fw: loops
Serdar Tumgoren zstumgo...@gmail.com wrote http://www.freenetpages.co.uk/hp/alan.gauld/ Note the new URL in my sig. Freenet are due to close this site soon. Its been locked for over a year. -- Alan Gauld 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] duplication in unit tests
On 12/9/2009 10:43 AM, Kent Johnson wrote: So my questions -- Am I misunderstanding how to properly write unit tests for this case? Or perhaps I've structured my program incorrectly, and that's what this duplication reveals? I suspected, for instance, that perhaps I should group these methods (convertEmDashes, splitLines, etc.) into a single larger function or method. Yes, your tests are revealing a problem with the structure. You should probably have a single process() method that does all the cleanup methods and the split. Then you could also have a test for this. I should add, a unittest can be a white-box testing. You can have TestCases for the whole process (blackbox test), but you can also have TestCases for each splitLine, convertEmDashes, etc (whitebox test). The test for the large process will be, sort of, a simple integration test for each sub-processes. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] duplication in unit tests
Hi Kent and Lie, First, thanks to you both for the help. I reworked the tests and then the main code according to your suggestions (I really was muddling these TDD concepts!). The reworked code and tests are below. In the tests, I hard-coded the source data and the expected results; in the main program code, I eliminated the FileCleaner class and converted its methods to stand-alone functions. I'm planning to group them into a single, larger process function as you all suggested. Meantime, I'd be grateful if you could critique whether I've properly followed your advice. And of course, feel free to suggest other tests that might be appropriate. For instance, would it make sense to test convertEmDashes for non-unicode input? Thanks again! Serdar test_cleaner.py from cleaner import convertEmDashes, splitLines class TestCleanerMethods(unittest.TestCase): def test_convertEmDashes(self): convertEmDashes to minus signs srce = uThisline has an em\u2014dash.\nSo does this \u2014.\n expected = uThisline has an em-dash.\nSo does this -.\n result = convertEmDashes(srce) self.assertEqual(result, expected) def test_splitLines(self): splitLines should create a list of cleaned lines srce = uThisline has an em\u2014dash.\nSo does this \u2014.\n expected = [u'Thisline has an em\u2014dash.', u'So does this \u2014.'] result = splitLines(srce) self.assertEqual(result, expected) cleaner.py def convertEmDashes(datastring): Convert unicode emdashes to minus signs datastring = datastring.replace(u'\u2014','-') return datastring def splitLines(datastring): Generate list of cleaned lines data = [x.strip() for x in datastring.strip().split('\n') if x.strip()] return data ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] functions--how long is too long?
Thank you to all who replied. That does help me get a better idea of all this. I think if I apply a number of the thoughts expressed I can come to a good, readable re-do of these longer functions. Che _ Chat with Messenger straight from your Hotmail inbox. http://www.microsoft.com/windows/windowslive/hotmail_bl1/hotmail_bl1.aspx?ocid=PID23879::T:WLMTAGL:ON:WL:en-ww:WM_IMHM_4:092009___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] duplication in unit tests
On Tue, Dec 8, 2009 at 10:11 PM, Serdar Tumgoren zstumgo...@gmail.com wrote: Hi Kent and Lie, First, thanks to you both for the help. I reworked the tests and then the main code according to your suggestions (I really was muddling these TDD concepts!). The reworked code and tests are below. In the tests, I hard-coded the source data and the expected results; in the main program code, I eliminated the FileCleaner class and converted its methods to stand-alone functions. I'm planning to group them into a single, larger process function as you all suggested. Meantime, I'd be grateful if you could critique whether I've properly followed your advice. Yes, this is much better. Notice how much less code it is! :-) And of course, feel free to suggest other tests that might be appropriate. For instance, would it make sense to test convertEmDashes for non-unicode input? If you expect unicode input then it makes sense to test for it. If you don't expect unicode input, it might make sense to test for an expected error - how do you want the function to behave with invalid inputs? You could add other tests as well, for example does it work if there are two dashes in a row? Does splitLines() correctly remove blank lines? These are simple functions but the idea is to think of all the desired behaviours and write test cases to cover them. By the way I applaud your effort, unit testing is a valuable skill. Kent ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] numerical simulation + SQLite
On Tue, Dec 1, 2009 at 11:48 AM, Faisal Moledina faisal.moled...@gmail.com wrote: Eike Welk wrote: Just in case you don't know it, maybe Pytables is the right solution for you. It is a disk storage library specially for scientific applications: http://www.pytables.org/moin Wow, that looks pretty good. I work with a lot of numpy.array's in this simulation so I'll definitely look into that. For those of you following along at home, my problem has been solved with Pytables. Discussion available at http://www.mail-archive.com/pytables-us...@lists.sourceforge.net/msg01416.html on the Pytables-users list. Thanks again, Eike. Faisal ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] What books do you recommend?
Hi, I wan't to buy some books about python 3. Do you have any recommendations? I started with no previous programming experience, and I've finished a few tutorials and I guess I can be considered a beginner. My problem, though, is I still find it difficult to write meaningful code or use the built in libraries effectively and/or correctly because I can't find example code to mimic. I tried sifting through ActiveState recipes page, but most of the code seems uninteresting or useful only if utilized in a bigger project. I hope you have some suggestions. Thanks a lot. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] duplication in unit tests
Serdar Tumgoren wrote: Hi Kent and Lie, First, thanks to you both for the help. I reworked the tests and then the main code according to your suggestions (I really was muddling these TDD concepts!). The reworked code and tests are below. In the tests, I hard-coded the source data and the expected results; in the main program code, I eliminated the FileCleaner class and converted its methods to stand-alone functions. I'm planning to group them into a single, larger process function as you all suggested. Meantime, I'd be grateful if you could critique whether I've properly followed your advice. And of course, feel free to suggest other tests that might be appropriate. For instance, would it make sense to test convertEmDashes for non-unicode input? Thanks again! Serdar test_cleaner.py from cleaner import convertEmDashes, splitLines class TestCleanerMethods(unittest.TestCase): def test_convertEmDashes(self): convertEmDashes to minus signs srce = uThisline has an em\u2014dash.\nSo does this \u2014.\n expected = uThisline has an em-dash.\nSo does this -.\n result = convertEmDashes(srce) self.assertEqual(result, expected) def test_splitLines(self): splitLines should create a list of cleaned lines srce = uThisline has an em\u2014dash.\nSo does this \u2014.\n expected = [u'Thisline has an em\u2014dash.', u'So does this \u2014.'] result = splitLines(srce) self.assertEqual(result, expected) cleaner.py def convertEmDashes(datastring): Convert unicode emdashes to minus signs datastring = datastring.replace(u'\u2014','-') I think the 'dash' should be a unicode one, at least if you're expecting the datastring to be unicode. datastring = datastring.replace(u'\u2014',u'-') It will probably be slightly more efficient, but more importantly, it'll make it clear what you're expecting. return datastring def splitLines(datastring): Generate list of cleaned lines data = [x.strip() for x in datastring.strip().split('\n') if x.strip()] return data And in both these functions, the doc string doesn't reflect the function very well (any more). They both should indicate what kind of data they expect (unicode?), and the latter one should not say that the lines are cleaned. What it should say is that the lines in the list have no leading or trailing whitespace, and that blank lines are dropped. Once you have multiple cleanup functions, the unit tests become much more important. For example, the order of application of the cleanups could matter a lot. And pretty soon you'll have to document just what your public interface is. If your user may only call the overall cleanup() function, then blackbox testing only needs to examine that one, and whitebox testing can deal with the functions entirely independently. DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor