Re: [Tutor] urllib2 and tests
Thank you, I figured out what the problem was. I was passing in url into the test_file_fetch function instead of self. URL was a global. I did get the asserts mixed up. They were the opposite of what I wanted. Sorry I didn't include the whole test.py file for reference. Thanks again On Sat, May 4, 2013 at 9:08 PM, Steven D'Aprano wrote: > On 05/05/13 13:27, RJ Ewing wrote: > >> When I run the following test.py, I get the following error: >> > [...] > > If I run the fetch_file function outside of the test, it works fine. Any >> ideas? >> > > The code you are actually running, and the code you say you are running > below, are different. Your error message refers to a file > test_filefetcher.py, not the Test.py you show us. As given, Test.py cannot > possibly work, since it doesn't define "filefetcher". I can only guess that > this is meant to be the module you are trying to test, but since you don't > show us what is in that module, I can only guess what it contains. > > > More comments below: > > > > RROR: test_fetch_file (__main__.TestFileFetcher) >> --**--** >> -- >> Traceback (most recent call last): >>File "test_filefetcher.py", line 12, in test_fetch_file >> fetched_file = filefetcher.fetch_file(URL) >> > > What's filefetcher? I'm guessing its the module you are testing, which is > consistent with the next line showing the file name filefetcher.py: > > > > File "/Users/rjewing/Documents/**Work/filefetcher.py", line 7, in >> fetch_file >> return urllib2.urlopen(url).read() >>File >> "/Library/Frameworks/Python.**framework/Versions/2.7/lib/** >> python2.7/urllib2.py", >> line 126, in urlopen >> return _opener.open(url, data, timeout) >>File >> "/Library/Frameworks/Python.**framework/Versions/2.7/lib/** >> python2.7/urllib2.py", >> line 392, in open >> protocol = req.get_type() >> AttributeError: 'TestFileFetcher' object has no attribute 'get_type' >> > > > Somehow, your test suite, the TestFileFetcher object, is being passed down > into the urllib2 library. I can only guess that somehow url is not an > actual URL. I suggest you add a line: > > print(url, type(url)) > > just before the failing line, and see what it prints. > > > --**--** >> -- >> >> Test.py: >> > > This cannot be the actual test suite you are running, since it cannot run > as shown. It doesn't import unittest or the module to be tested. > > > > class TestFileFetcher(unittest.**TestCase): >> >> def test_fetch_file(URL): >> phrase = 'position = support-intern' >> >> fetched_file = filefetcher.fetch_file(URL) >> > > And here's your error! Just as I thought, URL is not what you think it is, > it is the TestFileFetcher instance. > > Unittest cases do not take arguments. Since they are methods, they are > always defined with a single argument, conventionally called "self", > representing the instance that the method is called on. So normally you > would define a method like this: > > def test_fetch_file(self, url): > > which then takes a single *implicit* argument "self", provided by Python, > plus a second *explicit* argument, "url". But because this is a test > method, the unittest framework does not expect to pass an argument to the > method, so you have to write it like this: > > def test_fetch_file(self): > > and get the url some other way. > > One common way would be to define an attribute on the test, and store the > URL in that: > > class TestFileFetcher(unittest.**TestCase): > URL = "some_url_goes_here" # FIX THIS > > def test_fetch_file(self): > > phrase = 'position = support-intern' > fetched_file = filefetcher.fetch_file(self.**URL) > ... > > > > > unittest.assertIsNone(fetched_**file, >>'The file was not fetched correctly') >> > > This part of the test seems to be wrong to me. It says: > > "compare the value of fetched_file to None; if it is None, the test > passes; if it is some other value, the test fails with error message 'The > file was not fetched correctly'" > > But then you immediately go on to use fetched_file: > > text = filefetc
[Tutor] urllib2 and tests
When I run the following test.py, I get the following error: RROR: test_fetch_file (__main__.TestFileFetcher) -- Traceback (most recent call last): File "test_filefetcher.py", line 12, in test_fetch_file fetched_file = filefetcher.fetch_file(URL) File "/Users/rjewing/Documents/Work/filefetcher.py", line 7, in fetch_file return urllib2.urlopen(url).read() File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 126, in urlopen return _opener.open(url, data, timeout) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 392, in open protocol = req.get_type() AttributeError: 'TestFileFetcher' object has no attribute 'get_type' -- Test.py: class TestFileFetcher(unittest.TestCase): def test_fetch_file(URL): phrase = 'position = support-intern' fetched_file = filefetcher.fetch_file(URL) unittest.assertIsNone(fetched_file, 'The file was not fetched correctly') text = filefetcher.add_phrase(fetched_file) unittest.assertNotIn(phrase, text, 'The phrase is not in the file') fetch_file(): def fetch_file(url): print 'Fetching file from %s' % url return urllib2.urlopen(url).read() If I run the fetch_file function outside of the test, it works fine. Any ideas? Thanks ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] implementing rot 13 problems
Thank you all for the help. I really appreciated the suggestions. Some of the things you pointed out, I originally used, but started changing thing when it wasn't working. I got it to work, but if you could let me know if there is anything I should do to make this code more pythonesque that would be great. def rot_text(self, s): ls = list(s) for position, char in enumerate(ls): if char.isupper() or char.islower(): test = 'M' if char.isupper() else 'm' if char <= test: ls[position] = chr(ord(char) + 13) else: ls[position] = chr(ord(char) - 13) return "".join(ls) On Tue, Mar 12, 2013 at 4:11 AM, Karim wrote: > > What can be said after this detailed lesson...Bravo! > > > On 12/03/2013 11:58, Steven D'Aprano wrote: > >> On 12/03/13 16:57, RJ Ewing wrote: >> >>> I am trying to implement rot 13 and am having troubles. My code is as >>> follows: >>> >> >> A few comments follow. >> >> >>def rot_text(self, s): >>> ls = [i for i in s] >>> for i in ls: >>> if i.isalpha(): >>> if i.isupper(): >>> if i <= 'M': >>> x = ls.index(i) >>> ls[ls.index(i)] = chr(ord(i) + 13) >>> >> >> >> This is unnecessarily verbose and complicated. >> >> First problem, you use the name "i" to represent a character. Generally >> you should avoid single character names, and prefer meaningful names that >> explain what the variable represents. If you must use a single character, >> then the conventional names include: >> >> x, y, z: numbers, particularly floats >> x: (rarely) an arbitrary value of no particular type >> i, j, k: integer loop variables (rare in Python) >> n, m: other integers >> s: string >> c: character >> >> Notice that "c for character" makes much more sense than "i for >> character". >> >> >> You can, and should, create a list from the string using the list() >> function, rather than a list comprehension that just walks over the >> characters: >> >> ls = [c for c in s] # No, too verbose. >> ls = list(s) # Much better. >> >> >> You then loop over the list, again using "i for character". You can >> combine all those multiple if statements into a single clause: >> >> for i in ls: >> if i.isalpha() and i.isupper() and i <= 'M': >> >> But wait! The call to isalpha() is not necessary, because if a character >> is *not* alphabetical, isupper() will always return False: >> >> py> '9'.isupper() >> False >> >> So we can throw out the call to isalpha(). >> >> Your code to rot13 the letter is, sadly, broken: >> >> x = ls.index(i) >> ls[ls.index(i)] = chr(ord(i) + 13) >> >> >> This might make more sense if I re-write it using more meaningful names: >> >> position = ls.index(char) # This variable never gets used :-( >> ls[ls.index(char)] = chr(ord(char) + 13) >> >> The bit with chr() and ord() is fine. But what you do with it is wrong. >> The problem is that index always returns the position of the *first* copy >> of the item. So if your string is: >> >> 'ABA' >> >> the first time around the loop, your character is 'A'. ls.index('A') will >> return 0, and the rot13ed version, 'N', will be shoved into position 0. The >> second time around the loop, the character is 'B' and the rot13ed version >> gets shoved into position 1. But the third time, the character is 'A' >> again, index() will return 0 again, and the rot13ed version gets shoved >> into position 0 instead of position 2, giving you: >> >> 'NOA' >> >> >> The best way to fix this is to ignore index, and instead count which >> character we're at each time: >> >> >> position = -1 >> for char in ls: >> position = position + 1 # Advance the count. >> ... blah blah blah >> ls[position] = chr(ord(char) + 13) >> >> >> But wait! Python has a function to do exactly this for us: >> >> >> for position, char in enumerate(ls): >> ... blah blah blah >> ls[position] = chr(ord(char) + 13) >> >> >> >> >> Have a go with that, and see how far you get. >> >> >> >> >> > __**_ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > http://mail.python.org/**mailman/listinfo/tutor<http://mail.python.org/mailman/listinfo/tutor> > ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] implementing rot 13 problems
I am trying to implement rot 13 and am having troubles. My code is as follows: class Rot_13(webapp2.RequestHandler): def write_form(self, user=""): self.response.out.write(rot_form % user) def get(self): self.write_form() def post(self): user = self.request.get("text") s = self.rot_text(user) print s s = "".join(s) self.escape_html(s) self.write_form(s) def rot_text(self, s): ls = [i for i in s] for i in ls: if i.isalpha(): if i.isupper(): if i <= 'M': x = ls.index(i) ls[ls.index(i)] = chr(ord(i) + 13) else: x = ls.index(i) ls[ls.index(i)] = chr(ord(i) - 13) elif i.islower(): if i <= 'm': x = ls.index(i) ls[x] = chr(ord(i) + 13) elif i > 'm': x = ls.index(i) ls[x] = chr(ord(i) - 13) return ls def escape_html(self, s): return cgi.escape(s, quote = True) Now if I enter abc, I get nop. But if I enter abcdefghijklmnop, I get abcqrstuvwxyznop. I have included print statements to check if ls[x] is changing and it is, but something is going wrong when I return the ls, and I am not quite sure what it is. Thanks ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor