From andy at reportlab.com Tue Nov 1 16:07:02 2011 From: andy at reportlab.com (Andy Robinson) Date: Tue, 1 Nov 2011 15:07:02 +0000 Subject: [python-uk] ReportLab is hiring - Wimbledon Message-ID: Hi everyone, We're hiring. http://www.reportlab.com/about/careers/ Best Regards, -- Andy Robinson Managing Director ReportLab Europe Ltd. Media House, 3 Palmerston Road, Wimbledon, London SW19 1PG, UK Tel +44-20-8545-1570 From pythonsheffield at gmail.com Thu Nov 3 14:08:35 2011 From: pythonsheffield at gmail.com (Daley Chetwynd) Date: Thu, 3 Nov 2011 13:08:35 +0000 Subject: [python-uk] Introduction to Python at GeekUp Nottingham Message-ID: Hi all, I've been invited to give an "Introduction to Python" talk and coding dojo at this month's GeekUp Nottingham. It's being held on Monday November 7th from 18:30 - 21:00 at Cape Bar in Nottingham city centre. I'll be giving a presentation for about 20-30 minutes on the history and usages of Python, then showing code for the key syntactical differences between Python and other languages. The group will then form into pairs and work their way through the Python Koans for the remainder of the session. More information can be found at: http://geekup.org/events/334/ If you're in the Nottingham area, are free on that night and would like to come along, it'd be useful to have a few experienced Python developers to help out. The majority of GeekUp Nottingham's regulars are .NET or Java developers. Thanks, Daley Chetwynd -------------- next part -------------- An HTML attachment was scrubbed... URL: From harry.percival at gmail.com Tue Nov 8 16:11:31 2011 From: harry.percival at gmail.com (Harry Percival) Date: Tue, 8 Nov 2011 15:11:31 +0000 Subject: [python-uk] Dojo / workshop on "TDD Django with Selenium" - any interest? In-Reply-To: References: Message-ID: Looks like Wednesday the 16th - eventbrite/lanyrd/something invitation to follow! On Fri, Oct 21, 2011 at 2:22 PM, Harry Percival wrote: > OK, am keen to keep the ball rolling on this! About 20 people have > expressed an interest. > > I don't think I'm going to try and co-opt the next "proper" dojo session > of Nov 4th, but I'd like to do it soon - maybe a week or two after that. > > Here's a doodle - expression your timeslot preference! > > http://www.doodle.com/x5sw7xmcpb92pbia > > location: probably skillsmatter, so Clerkenwell/Farrringdon/Old st. > > cheers all! > hp > > > > > On Fri, Oct 14, 2011 at 4:23 PM, Gabriel Reis wrote: > >> +1 here! >> >> >> Gabriel Reis >> >> >> >> On Fri, Oct 14, 2011 at 2:06 PM, James Browne >> wrote: >> > +1 from me too. Would definitely attend. >> > >> > Thanks, >> > >> > James Browne >> > >> > On 13 October 2011 17:26, Harry Percival >> wrote: >> >> >> >> Hi-ho python peeps, >> >> >> >> Would anyone be interested in a dojo / worksop on the topic of >> test-driven >> >> Django development, with Selenium? >> >> >> >> I've been working on a tutorial on the topic >> >> ( *) . I'm not >> claiming >> >> to be a massive expert, but it's what I've learned at work over the >> last >> >> year or so, so it's fresh in my mind... I'm pretty sure I could get a >> couple >> >> of (ex?) colleagues to help present... >> >> >> >> Would be aimed at beginners / people who don't know Selenium / people >> who >> >> want to learn Django the "right" way / people who want to learn TDD... >> If >> >> you already know Django and Selenium back to front, it would probably >> be of >> >> less interest, although there may be some interesting discussions >> around >> >> integrating the Django test runner, WebDriver vs Selenium-RC etc... >> >> >> >> So, trying to get an idea of numbers - would anyone be interested? >> London >> >> area, venue suggestions also gratefully accepted... >> >> >> >> HP >> >> >> >> * work in progress! for example, the .jar file really isn't >> necessary... >> >> >> >> -- >> >> ------------------------------ >> >> Harry J.W. Percival >> >> ------------------------------ >> >> @hjwp >> >> Mobile: +44 (0) 78877 02511 >> >> Skype: harry.percival >> >> >> >> >> >> _______________________________________________ >> >> python-uk mailing list >> >> python-uk at python.org >> >> http://mail.python.org/mailman/listinfo/python-uk >> >> >> > >> > >> > >> > >> > _______________________________________________ >> > python-uk mailing list >> > python-uk at python.org >> > http://mail.python.org/mailman/listinfo/python-uk >> > >> > >> _______________________________________________ >> python-uk mailing list >> python-uk at python.org >> http://mail.python.org/mailman/listinfo/python-uk >> > > > > -- > ------------------------------ > Harry J.W. Percival > ------------------------------ > Twitter: @hjwp > > Mobile: +44 (0) 78877 02511 > Skype: harry.percival > -- ------------------------------ Harry J.W. Percival ------------------------------ Twitter: @hjwp Mobile: +44 (0) 78877 02511 Skype: harry.percival -------------- next part -------------- An HTML attachment was scrubbed... URL: From mauve at mauveweb.co.uk Tue Nov 8 17:26:44 2011 From: mauve at mauveweb.co.uk (Daniel Pope) Date: Tue, 8 Nov 2011 16:26:44 +0000 Subject: [python-uk] Python Dojo Reading, 7pm 16th November, One Forbury Square Message-ID: <20111108162644.GE22058@mauve-laptop> Hello everyone. The next Reading Python Dojo will be at 7pm on Wednesday 16th November, at One Forbury Square, Reading, RG1 3BB. Before the coding starts, we will have a brief talk by Mal Minhas about his experiences trying to extract information from Excel files with Python. There is another ~15 minute slot available if anyone else would like to talk about a Python-related topic of any description. Please sign up for a ticket on our EventWax site to let us know who is coming, and whether you have any particular preference for pizza toppings, etc. https://rdgpydojo.eventwax.com/reading-python-dojo-number-2 Dan From harry.percival at gmail.com Wed Nov 9 17:34:24 2011 From: harry.percival at gmail.com (Harry Percival) Date: Wed, 9 Nov 2011 16:34:24 +0000 Subject: [python-uk] Dojo / workshop on "TDD Django with Selenium" - any interest? In-Reply-To: References: Message-ID: OK, the workshop is in exactly 1 week's time, here's the page on the skillsmatter site : http://skillsmatter.com/podcast/agile-testing/tdd-django-selenium Book now to avoid disappointment! i've got to keep capacity a bit limited, because it's meant to be an interactive workshop, not a talk... everyone needs to follow through on pcs etc etc. I think I've managed to get some sponsorship for beers & pizza too, will keep y'all posted! Here's my talk summary: This workshop will cover the same materials as the official Django Tutorial, but using TDD at every stage - so, before any production code gets written, we'll be writing functional tests (aka acceptance tests) with Selenium, and then detailed unit tests. Workshop outline: - project setup. django startproject, startapp. downloading selenium, and the automated FT runner (will be supplied) - testing the django-admin site. logging in, creating a Poll object, creating associated choices. - unit tests for django models - models.py - testing the 'normal' parts of the site - unit tests for django urls, views. the Django Test Client - urls.py, views.py - django templates - advanced topics (depending on time) - django forms - using mock. discussion: when to mock, when not to. - javascript unit testing Who is this for? Maybe you've done a bit of Python programming, and you're thinking of learning Django, and you want to do it "properly". Maybe you've done some test-driven web development in another language, and you want to find out about how it all works in the Python world. Or maybe you've been using Python and Django for ages, and you've always toyed with the idea of getting into TDD, but you've never quite got round to it, and you want to find out what it's really like, in practical terms. Or, maybe you've done some Python testing, but you've never used Selenium and you want to find out more about that. Why should you listen to me? I was lucky enough to get my first "proper" software development job about a year ago with a bunch of Extreme Programming fanatics, who've thoroughly inculcated me into their cult of Test-Driven development. Believe me when I say I'm contrary enough to have questioned every single practice, challenged every single decision, moaned about every extra minute spent doing "pointless" tests instead of writing "proper" code. But I've come round to the idea now, and whenever I've had to go back to some of my old projects which don't have tests, boy have I ever realised the wisdom of the approach. So, I've learnt from some really good people, and the learning process is still fresh in my mind, so I hope I'll be good at communicating it. Most importantly, I still have the passion of a recent convert, so I hope I'll be good at conveying some enthusiasm. thanks for all the interest! And, if you can't make it, I'm sure (as long as it goes well) that we can schedule a follow-up! HP On Tue, Nov 8, 2011 at 3:11 PM, Harry Percival wrote: > Looks like Wednesday the 16th - eventbrite/lanyrd/something invitation to > follow! > > On Fri, Oct 21, 2011 at 2:22 PM, Harry Percival > wrote: >> >> OK, am keen to keep the ball rolling on this!? About 20 people have >> expressed an interest. >> >> I don't think I'm going to try and co-opt the next "proper" dojo session >> of Nov 4th, but I'd like to do it soon - maybe a week or two after that. >> >> Here's a doodle - expression your timeslot preference! >> >> http://www.doodle.com/x5sw7xmcpb92pbia >> >> location: probably skillsmatter, so Clerkenwell/Farrringdon/Old st. >> >> cheers all! >> hp >> >> >> >> On Fri, Oct 14, 2011 at 4:23 PM, Gabriel Reis >> wrote: >>> >>> +1 here! >>> >>> >>> Gabriel Reis >>> >>> >>> >>> On Fri, Oct 14, 2011 at 2:06 PM, James Browne >>> wrote: >>> > +1 from me too. Would definitely attend. >>> > >>> > Thanks, >>> > >>> > James Browne >>> > >>> > On 13 October 2011 17:26, Harry Percival >>> > wrote: >>> >> >>> >> Hi-ho python peeps, >>> >> >>> >> Would anyone be interested in a dojo / worksop on the topic of >>> >> test-driven >>> >> Django development, with Selenium? >>> >> >>> >> I've been working on a tutorial on the topic >>> >> ( *) . I'm not >>> >> claiming >>> >> to be a massive expert, but it's what I've learned at work over the >>> >> last >>> >> year or so, so it's fresh in my mind... I'm pretty sure I could get a >>> >> couple >>> >> of (ex?) colleagues to help present... >>> >> >>> >> Would be aimed at beginners / people who don't know Selenium / people >>> >> who >>> >> want to learn Django the "right" way / people who want to learn TDD... >>> >> If >>> >> you already know Django and Selenium back to front, it would probably >>> >> be of >>> >> less interest, although there may be some interesting discussions >>> >> around >>> >> integrating the Django test runner, WebDriver vs Selenium-RC etc... >>> >> >>> >> So, trying to get an idea of numbers - would anyone be interested? >>> >> London >>> >> area, venue suggestions also gratefully accepted... >>> >> >>> >> HP >>> >> >>> >> * work in progress!? for example, the .jar file really isn't >>> >> necessary... >>> >> >>> >> -- >>> >> ------------------------------ >>> >> Harry J.W. Percival >>> >> ------------------------------ >>> >> @hjwp >>> >> Mobile:? +44 (0) 78877 02511 >>> >> Skype:? ? ? ?? harry.percival >>> >> >>> >> >>> >> _______________________________________________ >>> >> python-uk mailing list >>> >> python-uk at python.org >>> >> http://mail.python.org/mailman/listinfo/python-uk >>> >> >>> > >>> > >>> > >>> > >>> > _______________________________________________ >>> > python-uk mailing list >>> > python-uk at python.org >>> > http://mail.python.org/mailman/listinfo/python-uk >>> > >>> > >>> _______________________________________________ >>> python-uk mailing list >>> python-uk at python.org >>> http://mail.python.org/mailman/listinfo/python-uk >> >> >> >> -- >> ------------------------------ >> Harry J.W. Percival >> ------------------------------ >> Twitter: @hjwp >> Mobile:? +44 (0) 78877 02511 >> Skype:? ? ? ?? harry.percival > > > > -- > ------------------------------ > Harry J.W. Percival > ------------------------------ > Twitter: @hjwp > Mobile:? +44 (0) 78877 02511 > Skype:? ? ? ?? harry.percival > -- ------------------------------ Harry J.W. Percival ------------------------------ Twitter: @hjwp Mobile:? +44 (0) 78877 02511 Skype:? ? ? ?? harry.percival From pythonsheffield at gmail.com Thu Nov 10 09:56:27 2011 From: pythonsheffield at gmail.com (Daley Chetwynd) Date: Thu, 10 Nov 2011 08:56:27 +0000 Subject: [python-uk] Geek Cadets Dec 3rd - 4th Message-ID: Hi all, Ian Ibbotson of GIST in Sheffield is organising special Geek Cadets sessions in Sheffield on Saturday December 3rd and Sunday December 4th. Geek Cadets is a regular meeting that aims to introduce kids to programming, and has now been running for several months. Geek Cadets has been using the "Invent your Own Computer Games with Python" book for teaching kids about programming: http://www.amazon.co.uk/INVENT-COMPUTER-Sweigart-Paperback-May-01-2010/dp/B004NKYBMG/ref=sr_1_1?ie=UTF8&qid=1320914672&sr=8-1 On the weekend of Dec 3rd - 4th there will be a Saturday session on programming for younger kids from 9am - 11:15am, then a session on Sunday Dec 4th from 9:30am - 12pm for older kids aged 12+. The content of these two sessions has yet to be decided, but it will be a Python-based exercise for teaching programming to kids. We're looking for Python mentors to help out with these two sessions, so that the kids can work with experienced developers. If you'd like to get involved and are interested in teaching programming to kids, please get in touch. There is also a Global Day of Code Retreat session being held at the venue in Sheffield on the same day, for which places are still available: http://coderetreat.ning.com/events/global-day-of-code-retreat-in-sheffield-uk Thanks, Daley -------------- next part -------------- An HTML attachment was scrubbed... URL: From tartley at tartley.com Fri Nov 11 09:42:38 2011 From: tartley at tartley.com (Jonathan) Date: Fri, 11 Nov 2011 08:42:38 +0000 Subject: [python-uk] memoize & ordering of kwargs.items() Message-ID: <4EBCDFFE.9010805@tartley.com> Hey, I've been writing my own 'memoize' function a lot recently - I'm using it as an interview question. Here's what I've got (with a corresponding series of tests): def memoize(wrapped): cache = {} @wraps(wrapped) def wrapper(*args, **kwargs): key = (args, tuple(kwargs.items())) if key not in cache: cache[key] = wrapped(*args, **kwargs) return cache[key] return wrapper Yesterday a candidate pointed out that this is wrong because .items() for two equal dictionaries might return the (key,value) pairs in a different order, presumably dependent on the respective dictionary's history. This would produce a different 'key' and hence an erroneous cache miss. This implies that the second line of 'wrapper' should become: key = (args, tuple(sorted(kwargs.items()))) (I've added 'sorted') Looking at lru_cache, I see that is exactly how it is implemented there. http://hg.python.org/cpython/file/default/Lib/functools.py However, I'm unable to come up with a test that proves this is necessary. I'm can create two equal dictionaries which return their .items() in a different order: # The intent is that 'small.items()' comes out in a different order # than 'large.items()' small = {'x':1, 'y':5} large = {hex(i): i for i in range(257)} large.update(small) for i in range(257): del large[hex(i)] >>> print small.items() [('y', 5), ('x', 1)] >>> print large.items() [('x', 1), ('y', 5)] If I could magically transfer these dictionaries directly into the 'kwargs' of wrapper, then I think I'd be done. However, I have to pass these dictionaries in to wrapper via the '**' mechanism. Printing 'kwargs.items()' within 'wrapper' shows that equal dictionaries always return their items in the same order, so the 'sorted' call is apparently not necessary. Is 'sorted' really required? If so, how can I write a test to demonstrate it? Best regards, Jonathan -- Jonathan Hartley tartley at tartley.com http://tartley.com Made of meat. +44 7737 062 225 twitter/skype: tartley From tartley at tartley.com Fri Nov 11 09:48:00 2011 From: tartley at tartley.com (Jonathan) Date: Fri, 11 Nov 2011 08:48:00 +0000 Subject: [python-uk] memoize & ordering of kwargs.items() In-Reply-To: <5791530.8102.1321001096253.JavaMail.root@m08> References: <5791530.8102.1321001096253.JavaMail.root@m08> Message-ID: <4EBCE140.9060104@tartley.com> oops. wrong list. sorry all. The question still stands though, if anyone's interested. On 11/11/2011 08:42, Jonathan wrote: > Hey, > > I've been writing my own 'memoize' function a lot recently - I'm using > it as an interview question. > > Here's what I've got (with a corresponding series of tests): > > def memoize(wrapped): > > cache = {} > > @wraps(wrapped) > def wrapper(*args, **kwargs): > key = (args, tuple(kwargs.items())) > if key not in cache: > cache[key] = wrapped(*args, **kwargs) > return cache[key] > > return wrapper > > Yesterday a candidate pointed out that this is wrong because .items() > for two equal dictionaries might return the (key,value) pairs in a > different order, presumably dependent on the respective dictionary's > history. This would produce a different 'key' and hence an erroneous > cache miss. > > This implies that the second line of 'wrapper' should become: > > key = (args, tuple(sorted(kwargs.items()))) > > (I've added 'sorted') > Looking at lru_cache, I see that is exactly how it is implemented there. > http://hg.python.org/cpython/file/default/Lib/functools.py > > However, I'm unable to come up with a test that proves this is > necessary. I'm can create two equal dictionaries which return their > .items() in a different order: > > # The intent is that 'small.items()' comes out in a different > order > # than 'large.items()' > small = {'x':1, 'y':5} > large = {hex(i): i for i in range(257)} > large.update(small) > for i in range(257): > del large[hex(i)] > > >>> print small.items() > [('y', 5), ('x', 1)] > >>> print large.items() > [('x', 1), ('y', 5)] > > If I could magically transfer these dictionaries directly into the > 'kwargs' of wrapper, then I think I'd be done. However, I have to pass > these dictionaries in to wrapper via the '**' mechanism. Printing > 'kwargs.items()' within 'wrapper' shows that equal dictionaries always > return their items in the same order, so the 'sorted' call is > apparently not necessary. > > Is 'sorted' really required? If so, how can I write a test to > demonstrate it? > > Best regards, > > Jonathan > -- Jonathan Hartley tartley at tartley.com http://tartley.com Made of meat. +44 7737 062 225 twitter/skype: tartley From renesd at gmail.com Fri Nov 11 09:49:58 2011 From: renesd at gmail.com (=?ISO-8859-1?Q?Ren=E9_Dudfield?=) Date: Fri, 11 Nov 2011 09:49:58 +0100 Subject: [python-uk] memoize & ordering of kwargs.items() In-Reply-To: <4EBCDFFE.9010805@tartley.com> References: <4EBCDFFE.9010805@tartley.com> Message-ID: Good morning, 1. Run it on different versions of python, or on different machines/OSes. That usually results in different dictionary ordering. 2. create a dict subclass that returns items always randomised. class my_fun_randomising_item_dict_subclass(dict): def items(self): return random.shuffle(dict.items(self, key)) def make_key(kwargs): return (args, tuple(sorted(my_fun_randomising_item_dict_subclass(kwargs).items()))) cheers, On Fri, Nov 11, 2011 at 9:42 AM, Jonathan wrote: > Hey, > > I've been writing my own 'memoize' function a lot recently - I'm using it > as an interview question. > > Here's what I've got (with a corresponding series of tests): > > def memoize(wrapped): > > cache = {} > > @wraps(wrapped) > def wrapper(*args, **kwargs): > key = (args, tuple(kwargs.items())) > if key not in cache: > cache[key] = wrapped(*args, **kwargs) > return cache[key] > > return wrapper > > Yesterday a candidate pointed out that this is wrong because .items() for > two equal dictionaries might return the (key,value) pairs in a different > order, presumably dependent on the respective dictionary's history. This > would produce a different 'key' and hence an erroneous cache miss. > > This implies that the second line of 'wrapper' should become: > > key = (args, tuple(sorted(kwargs.items()))) > > (I've added 'sorted') > Looking at lru_cache, I see that is exactly how it is implemented there. > http://hg.python.org/cpython/**file/default/Lib/functools.py > > However, I'm unable to come up with a test that proves this is necessary. > I'm can create two equal dictionaries which return their .items() in a > different order: > > # The intent is that 'small.items()' comes out in a different order > # than 'large.items()' > small = {'x':1, 'y':5} > large = {hex(i): i for i in range(257)} > large.update(small) > for i in range(257): > del large[hex(i)] > > >>> print small.items() > [('y', 5), ('x', 1)] > >>> print large.items() > [('x', 1), ('y', 5)] > > If I could magically transfer these dictionaries directly into the > 'kwargs' of wrapper, then I think I'd be done. However, I have to pass > these dictionaries in to wrapper via the '**' mechanism. Printing > 'kwargs.items()' within 'wrapper' shows that equal dictionaries always > return their items in the same order, so the 'sorted' call is apparently > not necessary. > > Is 'sorted' really required? If so, how can I write a test to demonstrate > it? > > Best regards, > > Jonathan > > -- > Jonathan Hartley tartley at tartley.com http://tartley.com > Made of meat. +44 7737 062 225 twitter/skype: tartley > > > ______________________________**_________________ > python-uk mailing list > python-uk at python.org > http://mail.python.org/**mailman/listinfo/python-uk > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ross.lawley at gmail.com Fri Nov 11 09:50:40 2011 From: ross.lawley at gmail.com (Ross Lawley) Date: Fri, 11 Nov 2011 08:50:40 +0000 Subject: [python-uk] memoize & ordering of kwargs.items() In-Reply-To: <4EBCDFFE.9010805@tartley.com> References: <4EBCDFFE.9010805@tartley.com> Message-ID: Hi, >From the docs: http://docs.python.org/library/stdtypes.html#dict.items "CPython implementation detail: Keys and values are listed in an arbitrary order which is non-random, varies across Python implementations, and depends on the dictionary?s history of insertions and deletions." Given that I would use sorted to guarantee order. Then no matter what anyone has done to the kwargs passed in the memoizing will not have a bug. Ross On Fri, Nov 11, 2011 at 8:42 AM, Jonathan wrote: > Hey, > > I've been writing my own 'memoize' function a lot recently - I'm using it > as an interview question. > > Here's what I've got (with a corresponding series of tests): > > def memoize(wrapped): > > cache = {} > > @wraps(wrapped) > def wrapper(*args, **kwargs): > key = (args, tuple(kwargs.items())) > if key not in cache: > cache[key] = wrapped(*args, **kwargs) > return cache[key] > > return wrapper > > Yesterday a candidate pointed out that this is wrong because .items() for > two equal dictionaries might return the (key,value) pairs in a different > order, presumably dependent on the respective dictionary's history. This > would produce a different 'key' and hence an erroneous cache miss. > > This implies that the second line of 'wrapper' should become: > > key = (args, tuple(sorted(kwargs.items()))) > > (I've added 'sorted') > Looking at lru_cache, I see that is exactly how it is implemented there. > http://hg.python.org/cpython/**file/default/Lib/functools.py > > However, I'm unable to come up with a test that proves this is necessary. > I'm can create two equal dictionaries which return their .items() in a > different order: > > # The intent is that 'small.items()' comes out in a different order > # than 'large.items()' > small = {'x':1, 'y':5} > large = {hex(i): i for i in range(257)} > large.update(small) > for i in range(257): > del large[hex(i)] > > >>> print small.items() > [('y', 5), ('x', 1)] > >>> print large.items() > [('x', 1), ('y', 5)] > > If I could magically transfer these dictionaries directly into the > 'kwargs' of wrapper, then I think I'd be done. However, I have to pass > these dictionaries in to wrapper via the '**' mechanism. Printing > 'kwargs.items()' within 'wrapper' shows that equal dictionaries always > return their items in the same order, so the 'sorted' call is apparently > not necessary. > > Is 'sorted' really required? If so, how can I write a test to demonstrate > it? > > Best regards, > > Jonathan > > -- > Jonathan Hartley tartley at tartley.com http://tartley.com > Made of meat. +44 7737 062 225 twitter/skype: tartley > > > ______________________________**_________________ > python-uk mailing list > python-uk at python.org > http://mail.python.org/**mailman/listinfo/python-uk > -------------- next part -------------- An HTML attachment was scrubbed... URL: From tartley at tartley.com Fri Nov 11 10:23:45 2011 From: tartley at tartley.com (Jonathan) Date: Fri, 11 Nov 2011 09:23:45 +0000 Subject: [python-uk] memoize & ordering of kwargs.items() In-Reply-To: <1292795.8258.1321001700390.JavaMail.root@m08> References: <4EBCDFFE.9010805@tartley.com> <1292795.8258.1321001700390.JavaMail.root@m08> Message-ID: <4EBCE9A1.6010701@tartley.com> That's good to know Ren?, but I *think* it's orthogonal to the question. Please correct me if I'm wrong. If PyPy returns items in a different order than CPython, that doesn't matter to me, so long as every invocation of my function in a particular process ends up receiving a particular order, that doesn't change until the process ends (or the cache is cleared.) The dict subclass is a great idea - but if the change in order isn't ever manifested by a regular dict, then it implies to me that the 'sorted' call isn't actually required in real life, so the need for this whole test disappears. See also my imminent reply to Ross. Jonathan On 11/11/2011 08:49, Ren? Dudfield wrote: > Good morning, > > 1. Run it on different versions of python, or on different > machines/OSes. That usually results in different dictionary ordering. > 2. create a dict subclass that returns items always randomised. > > class my_fun_randomising_item_dict_subclass(dict): > def items(self): > return random.shuffle(dict.items(self, key)) > def make_key(kwargs): > return (args, > tuple(sorted(my_fun_randomising_item_dict_subclass(kwargs).items()))) > > cheers, > > On Fri, Nov 11, 2011 at 9:42 AM, Jonathan > wrote: > > Hey, > > I've been writing my own 'memoize' function a lot recently - I'm > using it as an interview question. > > Here's what I've got (with a corresponding series of tests): > > def memoize(wrapped): > > cache = {} > > @wraps(wrapped) > def wrapper(*args, **kwargs): > key = (args, tuple(kwargs.items())) > if key not in cache: > cache[key] = wrapped(*args, **kwargs) > return cache[key] > > return wrapper > > Yesterday a candidate pointed out that this is wrong because > .items() for two equal dictionaries might return the (key,value) > pairs in a different order, presumably dependent on the respective > dictionary's history. This would produce a different 'key' and > hence an erroneous cache miss. > > This implies that the second line of 'wrapper' should become: > > key = (args, tuple(sorted(kwargs.items()))) > > (I've added 'sorted') > Looking at lru_cache, I see that is exactly how it is implemented > there. > http://hg.python.org/cpython/file/default/Lib/functools.py > > However, I'm unable to come up with a test that proves this is > necessary. I'm can create two equal dictionaries which return > their .items() in a different order: > > # The intent is that 'small.items()' comes out in a > different order > # than 'large.items()' > small = {'x':1, 'y':5} > large = {hex(i): i for i in range(257)} > large.update(small) > for i in range(257): > del large[hex(i)] > > >>> print small.items() > [('y', 5), ('x', 1)] > >>> print large.items() > [('x', 1), ('y', 5)] > > If I could magically transfer these dictionaries directly into the > 'kwargs' of wrapper, then I think I'd be done. However, I have to > pass these dictionaries in to wrapper via the '**' mechanism. > Printing 'kwargs.items()' within 'wrapper' shows that equal > dictionaries always return their items in the same order, so the > 'sorted' call is apparently not necessary. > > Is 'sorted' really required? If so, how can I write a test to > demonstrate it? > > Best regards, > > Jonathan > > -- > Jonathan Hartley tartley at tartley.com > http://tartley.com > Made of meat. +44 7737 062 225 > twitter/skype: tartley > > > _______________________________________________ > python-uk mailing list > python-uk at python.org > http://mail.python.org/mailman/listinfo/python-uk > > > > > _______________________________________________ > python-uk mailing list > python-uk at python.org > http://mail.python.org/mailman/listinfo/python-uk -- Jonathan Hartley tartley at tartley.com http://tartley.com Made of meat. +44 7737 062 225 twitter/skype: tartley -------------- next part -------------- An HTML attachment was scrubbed... URL: From duncan.booth at suttoncourtenay.org.uk Fri Nov 11 10:24:38 2011 From: duncan.booth at suttoncourtenay.org.uk (Duncan Booth) Date: Fri, 11 Nov 2011 09:24:38 +0000 Subject: [python-uk] memoize & ordering of kwargs.items() In-Reply-To: References: <4EBCDFFE.9010805@tartley.com> Message-ID: On Fri, Nov 11, 2011 at 8:50 AM, Ross Lawley wrote: >> However, I'm unable to come up with a test that proves this is necessary. >> I'm can create two equal dictionaries which return their .items() in a >> different order: >> >> ? ? ? ?# The intent is that 'small.items()' comes out in a different order >> ? ? ? ?# than 'large.items()' >> ? ? ? ?small = {'x':1, 'y':5} >> ? ? ? ?large = {hex(i): i for i in range(257)} >> ? ? ? ?large.update(small) >> ? ? ? ?for i in range(257): >> ? ? ? ? ? ?del large[hex(i)] >> There are two ways to create dictionaries that are equal but have their keys in different order. The way you used ends up with a very sparse dictionary after you deleted the padding keys. When you call a function it copies the kwargs dictionary so at that point the sparseness is lost as is your artificial key ordering. The other way is simply to pick keys that that hash to the same value modulo the size of the dictionary. Since the dictionary copy copies the keys in the order they are stored you will get the same hash conflict in the copy as the original. >> Is 'sorted' really required? If so, how can I write a test to demonstrate >> it? This should help you: >>> def foo(**kw): print(kw) >>> foo(a=None, i=None) {'a': None, 'i': None} >>> foo(i=None, a=None) {'i': None, 'a': None} >>> And here's an easy way to find some conflicts. You could use this code to find a conflict instead of hardwiring the argument names in the test. >>> for p, q in itertools.product(ascii_letters, ascii_letters): d1, d2 = {p:None, q:None}, {q:None, p:None} if repr(d1) != repr(d2): print(d1) count += 1 if count > 20: break {'a': None, 'i': None} {'a': None, 'q': None} {'a': None, 'y': None} {'a': None, 'A': None} {'a': None, 'I': None} {'a': None, 'Q': None} {'a': None, 'Y': None} {'b': None, 'j': None} {'b': None, 'z': None} {'c': None, 'k': None} {'c': None, 's': None} {'c': None, 'C': None} {'c': None, 'K': None} {'c': None, 'S': None} {'d': None, 'l': None} {'d': None, 't': None} {'d': None, 'D': None} {'d': None, 'L': None} {'d': None, 'T': None} {'m': None, 'e': None} {'u': None, 'e': None} From tartley at tartley.com Fri Nov 11 10:30:23 2011 From: tartley at tartley.com (Jonathan) Date: Fri, 11 Nov 2011 09:30:23 +0000 Subject: [python-uk] memoize & ordering of kwargs.items() In-Reply-To: <18292272.8259.1321001700445.JavaMail.root@m08> References: <4EBCDFFE.9010805@tartley.com> <18292272.8259.1321001700445.JavaMail.root@m08> Message-ID: <4EBCEB2F.9000804@tartley.com> Thanks Ross. The thing is, the 'kwargs' dict that callers pass in is not the same dict as the kwargs that my wrapper function receives. My 'wrapper' function always receives a brand-new dictionary, created from scratch as the function is invoked. Hence, the kwargs never has any 'history' - they are always newly created, from the keyword args passed in to the function. This, I suspect, is why their 'items()' always appear in the same order. I tried calling 'wrapper' with keyword args in a different order: wrapper(x=1, y=2, z=3) wrapper(y=2, x=1, z=3) ...etc, for every permutation and by passing in **kwargs dictionaries with different histories (detailed in my original mail): wrapper(**kwargs) but in every case, inside wrapper... def wrapper(*args, **kwargs): print kwargs.items() ...the items call always returns the dictionary's content in the same order. So I *suspect*, but cannot yet prove, that the '**' mechanism is already sorting the keyword args used to construct the kwargs dictionary (or is doing some equivalent, such that the dicts always end up identical-including-order-of-items()) I agree that 'to be sure' is enough of a justification for including the 'sorted' call anyway. But it irks me that I can't write a test to show it. Jonathan On 11/11/2011 08:50, Ross Lawley wrote: > Hi, > > From the docs: http://docs.python.org/library/stdtypes.html#dict.items > > "CPython implementation detail: Keys and values are listed in an > arbitrary order which is non-random, varies across Python > implementations, and depends on the dictionary's history of insertions > and deletions." > > Given that I would use sorted to guarantee order. Then no matter what > anyone has done to the kwargs passed in the memoizing will not have a bug. > > Ross > > On Fri, Nov 11, 2011 at 8:42 AM, Jonathan > wrote: > > Hey, > > I've been writing my own 'memoize' function a lot recently - I'm > using it as an interview question. > > Here's what I've got (with a corresponding series of tests): > > def memoize(wrapped): > > cache = {} > > @wraps(wrapped) > def wrapper(*args, **kwargs): > key = (args, tuple(kwargs.items())) > if key not in cache: > cache[key] = wrapped(*args, **kwargs) > return cache[key] > > return wrapper > > Yesterday a candidate pointed out that this is wrong because > .items() for two equal dictionaries might return the (key,value) > pairs in a different order, presumably dependent on the respective > dictionary's history. This would produce a different 'key' and > hence an erroneous cache miss. > > This implies that the second line of 'wrapper' should become: > > key = (args, tuple(sorted(kwargs.items()))) > > (I've added 'sorted') > Looking at lru_cache, I see that is exactly how it is implemented > there. > http://hg.python.org/cpython/file/default/Lib/functools.py > > However, I'm unable to come up with a test that proves this is > necessary. I'm can create two equal dictionaries which return > their .items() in a different order: > > # The intent is that 'small.items()' comes out in a > different order > # than 'large.items()' > small = {'x':1, 'y':5} > large = {hex(i): i for i in range(257)} > large.update(small) > for i in range(257): > del large[hex(i)] > > >>> print small.items() > [('y', 5), ('x', 1)] > >>> print large.items() > [('x', 1), ('y', 5)] > > If I could magically transfer these dictionaries directly into the > 'kwargs' of wrapper, then I think I'd be done. However, I have to > pass these dictionaries in to wrapper via the '**' mechanism. > Printing 'kwargs.items()' within 'wrapper' shows that equal > dictionaries always return their items in the same order, so the > 'sorted' call is apparently not necessary. > > Is 'sorted' really required? If so, how can I write a test to > demonstrate it? > > Best regards, > > Jonathan > > -- > Jonathan Hartley tartley at tartley.com > http://tartley.com > Made of meat. +44 7737 062 225 > twitter/skype: tartley > > > _______________________________________________ > python-uk mailing list > python-uk at python.org > http://mail.python.org/mailman/listinfo/python-uk > > > > > _______________________________________________ > python-uk mailing list > python-uk at python.org > http://mail.python.org/mailman/listinfo/python-uk -- Jonathan Hartley tartley at tartley.com http://tartley.com Made of meat. +44 7737 062 225 twitter/skype: tartley -------------- next part -------------- An HTML attachment was scrubbed... URL: From renesd at gmail.com Fri Nov 11 10:34:37 2011 From: renesd at gmail.com (=?ISO-8859-1?Q?Ren=E9_Dudfield?=) Date: Fri, 11 Nov 2011 10:34:37 +0100 Subject: [python-uk] memoize & ordering of kwargs.items() In-Reply-To: <4EBCE9A1.6010701@tartley.com> References: <4EBCDFFE.9010805@tartley.com> <1292795.8258.1321001700390.JavaMail.root@m08> <4EBCE9A1.6010701@tartley.com> Message-ID: On Fri, Nov 11, 2011 at 10:23 AM, Jonathan wrote: > That's good to know Ren?, but I *think* it's orthogonal to the question. > Please correct me if I'm wrong. > > If PyPy returns items in a different order than CPython, that doesn't > matter to me, so long as every invocation of my function in a particular > process ends up receiving a particular order, that doesn't change until > the process ends (or the cache is cleared.) > > The dict subclass is a great idea - but if the change in order isn't ever > manifested by a regular dict, then it implies to me that the 'sorted' call > isn't actually required in real life, so the need for this whole test > disappears. > > See also my imminent reply to Ross. > > Jonathan > > > Just because your code works Now, does not mean it will work in the future. Especially when the ordering is explicitly marked as a non-deterministic implementation detail. Relying on it to be deterministic when it is stated to be non-deterministic will mean that in the future you could get a failure. Relying on implementation quirks is fine, but not reliable. In your case though, the worst that can happen now is a cache miss. In the future though, your cache could be completely useless because every time the data could be in a different order. Testing on multiple platforms allows you to sometimes see a failure condition, which lets you test it. Likewise, using a randomised dict subclass will let you test your code as if there is an error condition. cya. ps. my randomised items subclass is buggy... I forgot that random.shuffle works in place, and doesn't return a shuffled sequence. -------------- next part -------------- An HTML attachment was scrubbed... URL: From tartley at tartley.com Fri Nov 11 10:35:00 2011 From: tartley at tartley.com (Jonathan) Date: Fri, 11 Nov 2011 09:35:00 +0000 Subject: [python-uk] memoize & ordering of kwargs.items() In-Reply-To: <21576085.8747.1321003633024.JavaMail.root@m08> References: <4EBCDFFE.9010805@tartley.com> <21576085.8747.1321003633024.JavaMail.root@m08> Message-ID: <4EBCEC44.7010101@tartley.com> On 11/11/2011 09:24, Duncan Booth wrote: > pick keys that that hash to the same value modulo the size of the > dictionary. Since the dictionary copy copies the keys in the order > they are stored you will get the same hash conflict in the copy as the > original. Brilliant, thank-you. So I was just being 'lucky' in my choices of dict keys. I believe this is the answer I am looking for. Ren? & Ross's point about being mindful of different implementations is still very pertinent in my mind, but I'm happy for now. Thanks everyone! Jonathan -- Jonathan Hartley tartley at tartley.com http://tartley.com Made of meat. +44 7737 062 225 twitter/skype: tartley From tartley at tartley.com Fri Nov 11 11:14:50 2011 From: tartley at tartley.com (Jonathan) Date: Fri, 11 Nov 2011 10:14:50 +0000 Subject: [python-uk] memoize & ordering of kwargs.items() In-Reply-To: <20381834.8896.1321004237436.JavaMail.root@m08> References: <4EBCDFFE.9010805@tartley.com> <1292795.8258.1321001700390.JavaMail.root@m08> <4EBCE9A1.6010701@tartley.com> <20381834.8896.1321004237436.JavaMail.root@m08> Message-ID: <4EBCF59A.8090207@tartley.com> On 11/11/2011 09:34, Ren? Dudfield wrote: > On Fri, Nov 11, 2011 at 10:23 AM, Jonathan > wrote: > > That's good to know Ren?, but I *think* it's orthogonal to the > question. Please correct me if I'm wrong. > > If PyPy returns items in a different order than CPython, that > doesn't matter to me, so long as every invocation of my function > in a particular process ends up receiving a particular order, > that doesn't change until the process ends (or the cache is cleared.) > > The dict subclass is a great idea - but if the change in order > isn't ever manifested by a regular dict, then it implies to me > that the 'sorted' call isn't actually required in real life, so > the need for this whole test disappears. > > See also my imminent reply to Ross. > > Jonathan > > > > Just because your code works Now, does not mean it will work in the > future. Especially when the ordering is explicitly marked as a > non-deterministic implementation detail. Relying on it to be > deterministic when it is stated to be non-deterministic will mean that > in the future you could get a failure. > > Relying on implementation quirks is fine, but not reliable. In your > case though, the worst that can happen now is a cache miss. In the > future though, your cache could be completely useless because every > time the data could be in a different order. > > Testing on multiple platforms allows you to sometimes see a failure > condition, which lets you test it. Likewise, using a randomised dict > subclass will let you test your code as if there is an error condition. > > cya. > > ps. my randomised items subclass is buggy... I forgot that > random.shuffle works in place, and doesn't return a shuffled sequence. > > > _______________________________________________ > python-uk mailing list > python-uk at python.org > http://mail.python.org/mailman/listinfo/python-uk Hey Ren?, Thanks for that! I guess I was getting distracted because I was interpreting the situation as the fact that .items() for an *arbitrary* dictionary may well be non-deterministic, but in this particular case, for dictionaries newly-created by the '**' mechanism, they appear to be non-deterministic. I was forgetting that this is (presumably) also an implementation detail. Regardless, it sounds like you are probably right on all counts. Thanks for your enlightening thoughts. Cheers, Jonathan -- Jonathan Hartley tartley at tartley.com http://tartley.com Made of meat. +44 7737 062 225 twitter/skype: tartley -------------- next part -------------- An HTML attachment was scrubbed... URL: From tartley at tartley.com Fri Nov 11 12:14:42 2011 From: tartley at tartley.com (Jonathan) Date: Fri, 11 Nov 2011 11:14:42 +0000 Subject: [python-uk] memoize & ordering of kwargs.items() In-Reply-To: <301827.8897.1321004237486.JavaMail.root@m08> References: <4EBCDFFE.9010805@tartley.com> <21576085.8747.1321003633024.JavaMail.root@m08> <301827.8897.1321004237486.JavaMail.root@m08> Message-ID: <4EBD03A2.1060501@tartley.com> On 11/11/2011 09:35, Jonathan wrote: > On 11/11/2011 09:24, Duncan Booth wrote: >> pick keys that that hash to the same value modulo the size of the >> dictionary. Since the dictionary copy copies the keys in the order >> they are stored you will get the same hash conflict in the copy as >> the original. > > Brilliant, thank-you. So I was just being 'lucky' in my choices of > dict keys. I believe this is the answer I am looking for. Ren? & > Ross's point about being mindful of different implementations is still > very pertinent in my mind, but I'm happy for now. > > Thanks everyone! > > Jonathan > For completeness, my final test is therefore: def test_not_dependant_on_order_of_kwargs(self): calls = [] @memoize def counter(**kwargs): calls.append(1) for first in ascii_letters: for second in ascii_letters: forward = {first:0, second:0} reverse = {second:0, first:0} del calls[:] counter(**forward) counter(**reverse) self.assertEqual(len(calls), 1, '%d for %s,%s' % (len(calls), first, second)) Without the 'sorted', this fails with: ====================================================================== FAIL: test_not_dependant_on_order_of_kwargs (__main__.MemoizeTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "./test.py", line 58, in test_not_dependant_on_order_of_kwargs '%d for %s,%s' % (len(calls), first, second)) AssertionError: 2 for a,i ---------------------------------------------------------------------- Jubilant! Jonathan -- Jonathan Hartley tartley at tartley.com http://tartley.com Made of meat. +44 7737 062 225 twitter/skype: tartley From tartley at tartley.com Fri Nov 11 12:18:36 2011 From: tartley at tartley.com (Jonathan) Date: Fri, 11 Nov 2011 11:18:36 +0000 Subject: [python-uk] memoize & ordering of kwargs.items() In-Reply-To: <4EBD03A2.1060501@tartley.com> References: <4EBCDFFE.9010805@tartley.com> <21576085.8747.1321003633024.JavaMail.root@m08> <301827.8897.1321004237486.JavaMail.root@m08> <4EBD03A2.1060501@tartley.com> Message-ID: <4EBD048C.6040902@tartley.com> On 11/11/2011 11:14, Jonathan wrote: > On 11/11/2011 09:35, Jonathan wrote: >> On 11/11/2011 09:24, Duncan Booth wrote: >>> pick keys that that hash to the same value modulo the size of the >>> dictionary. Since the dictionary copy copies the keys in the order >>> they are stored you will get the same hash conflict in the copy as >>> the original. >> >> Brilliant, thank-you. So I was just being 'lucky' in my choices of >> dict keys. I believe this is the answer I am looking for. Ren? & >> Ross's point about being mindful of different implementations is >> still very pertinent in my mind, but I'm happy for now. >> >> Thanks everyone! >> >> Jonathan >> > > For completeness, my final test is therefore: > > def test_not_dependant_on_order_of_kwargs(self): > calls = [] > > @memoize > def counter(**kwargs): > calls.append(1) > > for first in ascii_letters: > for second in ascii_letters: > forward = {first:0, second:0} > reverse = {second:0, first:0} > > del calls[:] > counter(**forward) > counter(**reverse) > self.assertEqual(len(calls), 1, > '%d for %s,%s' % (len(calls), first, second)) > oops, but that doesn't pass with the 'sorted'. This does: for index, first in enumerate(ascii_letters): for second in ascii_letters[index:]: (i.e. I was testing each combination forwards and backwards, but then later in the iteration also testing them again, in the opposite order, which resulted in 0 extra calls to counter.) -- Jonathan Hartley tartley at tartley.com http://tartley.com Made of meat. +44 7737 062 225 twitter/skype: tartley From duncan.booth at suttoncourtenay.org.uk Fri Nov 11 12:21:17 2011 From: duncan.booth at suttoncourtenay.org.uk (Duncan Booth) Date: Fri, 11 Nov 2011 11:21:17 +0000 Subject: [python-uk] memoize & ordering of kwargs.items() In-Reply-To: <4EBCF59A.8090207@tartley.com> References: <4EBCDFFE.9010805@tartley.com> <1292795.8258.1321001700390.JavaMail.root@m08> <4EBCE9A1.6010701@tartley.com> <20381834.8896.1321004237436.JavaMail.root@m08> <4EBCF59A.8090207@tartley.com> Message-ID: On Fri, Nov 11, 2011 at 10:14 AM, Jonathan wrote: > Hey Ren?, > Thanks for that! I guess I was getting distracted because I was interpreting > the situation as the fact that .items() for an *arbitrary* dictionary may > well be non-deterministic, but in this particular case, for dictionaries > newly-created by the '**' mechanism, they appear to be non-deterministic. I > was forgetting that this is (presumably) also an implementation detail. > Regardless, it sounds like you are probably right on all counts. Thanks for > your enlightening thoughts. > Cheers, > ??? Jonathan Ren? is indeed correct to in what he says, but I think you are also correct to want to write a test case that shows the code is not depending on the dict order. Or in other words it is useful to have the counterexample I supplied, but the absence of a counterexample still wouldn't be an excuse for not fixing the code. Likewise there was a question on SO about using (s is "") to test for empty strings. There is a counterexample for Python 2.x but not so far as I know for Python 3.x but that still means people shouldn't do it in Python 3.x (the questioner in that case knew that but they wanted an example to throw at their colleague). From a.harrowell at gmail.com Fri Nov 11 13:54:10 2011 From: a.harrowell at gmail.com (Alexander Harrowell) Date: Fri, 11 Nov 2011 12:54:10 +0000 Subject: [python-uk] memoize & ordering of kwargs.items() In-Reply-To: <4EBCEB2F.9000804@tartley.com> References: <4EBCDFFE.9010805@tartley.com> <18292272.8259.1321001700445.JavaMail.root@m08> <4EBCEB2F.9000804@tartley.com> Message-ID: <201111111254.25767.a.harrowell@gmail.com> On Friday 11 Nov 2011 09:30:23 Jonathan wrote: > I agree that 'to be sure' is enough of a justification for including the 'sorted' call anyway. But it irks me that I can't write a test to show it. This is surely inherent in the fact that python dictionaries are not deterministically ordered. The dox don't say that you will always get key-val pairs back in *different* orders - just that you cannot rely on them being in the *same* order. Equally, you can't assume that they *won't*. Further, the dox also suggest that the behaviour is not truly random, so you can't rely on statistical randomness. You just have to avoid the whole idea of order when retrieving items from a python dictionary and treat it purely as a hash table that supports both a get-item-by-id behaviour and also some iterative and setwise methods. ISTR there are cases where two calls to dict.items() (and dict.keys() and dict.values()) *will* get the same order if there was no intervening write to the dict, but I suspect it's best to stick to the "right" behaviour. -- The only thing worse than e-mail disclaimers...is people who send e-mail to lists complaining about them -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: This is a digitally signed message part. URL: From matth at netsight.co.uk Fri Nov 11 14:02:18 2011 From: matth at netsight.co.uk (Matt Hamilton) Date: Fri, 11 Nov 2011 13:02:18 +0000 Subject: [python-uk] memoize & ordering of kwargs.items() In-Reply-To: <201111111254.25767.a.harrowell@gmail.com> References: <4EBCDFFE.9010805@tartley.com> <18292272.8259.1321001700445.JavaMail.root@m08> <4EBCEB2F.9000804@tartley.com> <201111111254.25767.a.harrowell@gmail.com> Message-ID: On 11 Nov 2011, at 12:54, Alexander Harrowell wrote: > This is surely inherent in the fact that python dictionaries are not deterministically ordered. The dox don't say that you will always get key-val pairs back in *different* orders - just that you cannot rely on them being in the *same* order. Equally, you can't assume that they *won't*. In CPython they *are* deterministically ordered though through their implementation. The API just states that for the purposes of the API you cannot rely on the order of the keys/values returned as that is a side effect of the implementation. -Matt > NETSIGHT > > Matt Hamilton > Technical Director > Email > matth at netsight.co.uk > > Telephone > +44 (0) 117 909 0901 > > > Web > www.netsight.co.uk > > Address > 40 Berkeley Square, Clifton > Bristol BS8 1HU -------------- next part -------------- An HTML attachment was scrubbed... URL: From tom at tomchristie.com Wed Nov 16 11:24:16 2011 From: tom at tomchristie.com (tom christie) Date: Wed, 16 Nov 2011 10:24:16 +0000 Subject: [python-uk] Dojo / workshop on "TDD Django with Selenium" - any interest? In-Reply-To: References: Message-ID: Hi all, I'm signed up, but not going to be able to make it this eve - if there's anyone on the waiting list, you might want to see if you can take my place. (BTW: Is anyone planning on videoing the session? That'd def be appreciated!) Also, it looks like this ticket: https://code.djangoproject.com/ticket/2879 is just about to go ready-for-checkin; which means `LiveServerTestCase` and `SeleniumTestCase` will be available in Django. Might be worth giving it a try - see if you can thrash out any last minute bugs. Cheers, t On 9 November 2011 16:34, Harry Percival wrote: > OK, the workshop is in exactly 1 week's time, here's the page on the > skillsmatter site : > > http://skillsmatter.com/podcast/agile-testing/tdd-django-selenium > > Book now to avoid disappointment! i've got to keep capacity a bit > limited, because it's meant to be an interactive workshop, not a > talk... everyone needs to follow through on pcs etc etc. > > I think I've managed to get some sponsorship for beers & pizza too, > will keep y'all posted! > > Here's my talk summary: > > This workshop will cover the same materials as the official Django > Tutorial, but using TDD at every stage - so, before any production > code gets written, we'll be writing functional tests (aka acceptance > tests) with Selenium, and then detailed unit tests. > > Workshop outline: > - project setup. django startproject, startapp. downloading > selenium, and the automated FT runner (will be supplied) > > - testing the django-admin site. logging in, creating a Poll object, > creating associated choices. > - unit tests for django models > - models.py > > - testing the 'normal' parts of the site > - unit tests for django urls, views. the Django Test Client > - urls.py, views.py > - django templates > > - advanced topics (depending on time) > - django forms > - using mock. discussion: when to mock, when not to. > - javascript unit testing > > > Who is this for? > > Maybe you've done a bit of Python programming, and you're thinking of > learning Django, and you want to do it "properly". Maybe you've done > some test-driven web development in another language, and you want to > find out about how it all works in the Python world. Or maybe you've > been using Python and Django for ages, and you've always toyed with > the idea of getting into TDD, but you've never quite got round to it, > and you want to find out what it's really like, in practical terms. > Or, maybe you've done some Python testing, but you've never used > Selenium and you want to find out more about that. > > Why should you listen to me? > > I was lucky enough to get my first "proper" software development job > about a year ago with a bunch of Extreme Programming fanatics, who've > thoroughly inculcated me into their cult of Test-Driven development. > Believe me when I say I'm contrary enough to have questioned every > single practice, challenged every single decision, moaned about every > extra minute spent doing "pointless" tests instead of writing "proper" > code. But I've come round to the idea now, and whenever I've had to go > back to some of my old projects which don't have tests, boy have I > ever realised the wisdom of the approach. > So, I've learnt from some really good people, and the learning process > is still fresh in my mind, so I hope I'll be good at communicating it. > Most importantly, I still have the passion of a recent convert, so I > hope I'll be good at conveying some enthusiasm. > > > thanks for all the interest! And, if you can't make it, I'm sure (as > long as it goes well) that we can schedule a follow-up! > > HP > On Tue, Nov 8, 2011 at 3:11 PM, Harry Percival > wrote: > > Looks like Wednesday the 16th - eventbrite/lanyrd/something invitation to > > follow! > > > > On Fri, Oct 21, 2011 at 2:22 PM, Harry Percival < > harry.percival at gmail.com> > > wrote: > >> > >> OK, am keen to keep the ball rolling on this! About 20 people have > >> expressed an interest. > >> > >> I don't think I'm going to try and co-opt the next "proper" dojo session > >> of Nov 4th, but I'd like to do it soon - maybe a week or two after that. > >> > >> Here's a doodle - expression your timeslot preference! > >> > >> http://www.doodle.com/x5sw7xmcpb92pbia > >> > >> location: probably skillsmatter, so Clerkenwell/Farrringdon/Old st. > >> > >> cheers all! > >> hp > >> > >> > >> > >> On Fri, Oct 14, 2011 at 4:23 PM, Gabriel Reis > >> wrote: > >>> > >>> +1 here! > >>> > >>> > >>> Gabriel Reis > >>> > >>> > >>> > >>> On Fri, Oct 14, 2011 at 2:06 PM, James Browne > >>> wrote: > >>> > +1 from me too. Would definitely attend. > >>> > > >>> > Thanks, > >>> > > >>> > James Browne > >>> > > >>> > On 13 October 2011 17:26, Harry Percival > >>> > wrote: > >>> >> > >>> >> Hi-ho python peeps, > >>> >> > >>> >> Would anyone be interested in a dojo / worksop on the topic of > >>> >> test-driven > >>> >> Django development, with Selenium? > >>> >> > >>> >> I've been working on a tutorial on the topic > >>> >> ( *) . I'm not > >>> >> claiming > >>> >> to be a massive expert, but it's what I've learned at work over the > >>> >> last > >>> >> year or so, so it's fresh in my mind... I'm pretty sure I could get > a > >>> >> couple > >>> >> of (ex?) colleagues to help present... > >>> >> > >>> >> Would be aimed at beginners / people who don't know Selenium / > people > >>> >> who > >>> >> want to learn Django the "right" way / people who want to learn > TDD... > >>> >> If > >>> >> you already know Django and Selenium back to front, it would > probably > >>> >> be of > >>> >> less interest, although there may be some interesting discussions > >>> >> around > >>> >> integrating the Django test runner, WebDriver vs Selenium-RC etc... > >>> >> > >>> >> So, trying to get an idea of numbers - would anyone be interested? > >>> >> London > >>> >> area, venue suggestions also gratefully accepted... > >>> >> > >>> >> HP > >>> >> > >>> >> * work in progress! for example, the .jar file really isn't > >>> >> necessary... > >>> >> > >>> >> -- > >>> >> ------------------------------ > >>> >> Harry J.W. Percival > >>> >> ------------------------------ > >>> >> @hjwp > >>> >> Mobile: +44 (0) 78877 02511 > >>> >> Skype: harry.percival > >>> >> > >>> >> > >>> >> _______________________________________________ > >>> >> python-uk mailing list > >>> >> python-uk at python.org > >>> >> http://mail.python.org/mailman/listinfo/python-uk > >>> >> > >>> > > >>> > > >>> > > >>> > > >>> > _______________________________________________ > >>> > python-uk mailing list > >>> > python-uk at python.org > >>> > http://mail.python.org/mailman/listinfo/python-uk > >>> > > >>> > > >>> _______________________________________________ > >>> python-uk mailing list > >>> python-uk at python.org > >>> http://mail.python.org/mailman/listinfo/python-uk > >> > >> > >> > >> -- > >> ------------------------------ > >> Harry J.W. Percival > >> ------------------------------ > >> Twitter: @hjwp > >> Mobile: +44 (0) 78877 02511 > >> Skype: harry.percival > > > > > > > > -- > > ------------------------------ > > Harry J.W. Percival > > ------------------------------ > > Twitter: @hjwp > > Mobile: +44 (0) 78877 02511 > > Skype: harry.percival > > > > > > -- > ------------------------------ > Harry J.W. Percival > ------------------------------ > Twitter: @hjwp > Mobile: +44 (0) 78877 02511 > Skype: harry.percival > _______________________________________________ > python-uk mailing list > python-uk at python.org > http://mail.python.org/mailman/listinfo/python-uk > -------------- next part -------------- An HTML attachment was scrubbed... URL: From tuck.daniel at gmail.com Fri Nov 25 18:14:47 2011 From: tuck.daniel at gmail.com (Daniel Tuck) Date: Fri, 25 Nov 2011 17:14:47 +0000 Subject: [python-uk] Python problem with ArcGIS Message-ID: http://www.esri.com/news/arcuser/0111/charmsnake.html ListLayers returns a Python list object containing layer objects. The str function converts a value (e.g., integer) to a string. Hi everyone, I'm trying to adapt the script on this page to return the workspace of every layer within an ArcGIS MXD? I think the stumbling block I'm up to is that I have a python list object and from there I'm having problems getting to the properties of the indivual layers. This is the code I have so far.. very messy in the middle! import os import sys import arcpy import arcpy.mapping as mapping # get input parameters outDir = arcpy.GetParameterAsText(0) packageMap = arcpy.GetParameter(1) checkBrokenLayers = arcpy.GetParameter(2) mxd_path = arcpy.GetParameter(3) # get the map document in which this code is running ("Current" keyword) mxd = mapping.MapDocument(mxd_path) # build a pathname to the output report (text file) reportPath = outDir + '\\' + 'test.txt' # open the file (will be created if it doesn't exist) reportFile = open(reportPath, 'w') arcpy.AddMessage('Writing report to ' + reportPath) # start writing report text to a string variable reportText = 'Title: ' + mxd.title + '\n' reportText += 'Author: ' + mxd.author + '\n' reportText += 'Description: ' + mxd.description + '\n' reportText += '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' + '\n' # if the user chose to do so, create map package if packageMap: packagePath = outDir + '\\' + mxd.title.replace('.', '_') + '.mpk' if (os.path.exists(packagePath)): arcpy.AddMessage('Map package already exists (' + packagePath + ')') else: arcpy.AddMessage('Creating map package (' + packagePath + ')' ) arcpy.PackageMap_management(mxd.filePath, packagePath) # loop thru all data frames in the map dataFrames = mapping.ListDataFrames(mxd, '') for frame in dataFrames: # report data frame name and spatial reference reportText += '\nData Frame: ' + frame.name + '\n' reportText += 'Spatial Reference: ' + frame.spatialReference.name + '\n' # get all layers in this data frame # "*" '' layers = mapping.ListLayers(mxd, '', frame) i = 0 # layer index position # loop thru all layers in the data frame for lyr in layers: # report index position and name - ' + lyr.longname + # so a python reference to the layer has been created # http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/Layer/00s300000008000000/ # now need to call it??? # here a list is being returned rather than the layer object itself? objLayer = arcpy.mapping.Layer(lyr) # i.e get object from layer reference LYR reportText += '\tLayer ' + str(i) + ': ' + lyr.name + ':' # + objLayer.workspace + '\n' i += 1 # same as i = i + 1 # if the user has requested it, check for layers with a missing data source if checkBrokenLayers: arcpy.AddMessage('Checking for missing data sources') brokenList = mapping.ListBrokenDataSources(mxd) # report the count of broken layers reportText += '\nFound ' + str(len(brokenList)) + ' layers with missing data.' # loop thru all broken layers in the list for broken in brokenList: # report broken layer name reportText += '\t- ' + broken.name + '\n' # write the text stored in the reportText variable to the output file reportFile.write(reportText) reportFile.close() # close the file del mxd # delete the mxd object Any help appreciated! Dan, -------------- next part -------------- An HTML attachment was scrubbed... URL: From Tibs at tibsnjoan.co.uk Sat Nov 26 20:37:41 2011 From: Tibs at tibsnjoan.co.uk (Tony Ibbs) Date: Sat, 26 Nov 2011 19:37:41 +0000 Subject: [python-uk] Next CamPUG meeting: Tue 6th Dec 2011 Message-ID: As posted to our google group: The next meeting should be a coding meeting, 7.30pm at RealVNC (http://tinyurl.com/realvncoffices). I imagine we may continue thinking about the code we worked on last time: http://groups.google.com/group/campug/msg/f63ffa366a64dd09 Meetings after that should be: * Tuesday 10th January, talks (note that this is the SECOND Tuesday) * Tuesday 7th February, dojo/coding * Tuesday 6th March, talks again Tibs From tim.abbott at zetman.com Thu Nov 3 10:55:17 2011 From: tim.abbott at zetman.com (Tim Abbott) Date: Thu, 03 Nov 2011 09:55:17 -0000 Subject: [python-uk] 2 x Python / Django Contract in London URGENT Message-ID: <003701cc9a0e$bdff5a30$39fe0e90$@abbott@zetman.com> Hi All, Just a quick one ? I need 2 Python / Django developers for a contract working on site in London. Skill wise literally all you need is a proven background with Python, Django and Linux OS and the ability to jump into a project that is reaching a critical point!! This part of the project is due to go live on the 17th Dec but the whole project is due to run until Dec 2012 and the company has a policy of re-using contractors who have worked for them before. Also, they are running a number of concurrent projects and may put you into other teams. Basically there is a lot of work!! The client is a digital agency based in central London (not far from Oxford Circus / Tottenham Court Road) and the end client is an automotive giant. The rate is ?250 - ?330pd depending on experience. If you are available and can help out they need 2 people ASAP. Please drop me your CV and I can get interviews sorted for the end of the week to start next week. If you are not available please can you forward this to anyone you know who is looking or becoming available in the next week or so and get them to call me. Regards, Tim Abbott Development Consultant Description: cid:image001.gif at 01CB33E9.75C76730 d/d: +44 (0)118 9256 144 t: +44 (0)118 9256 139 f: +44 (0)870 863 1001 e: tim.abbott at zetman.com w: www.zetman.com cid:image002.gif at 01C970C8.A7C2C760 This email and any attachments are intended solely for the addressees and may contain privileged information. If you are not an addressee, please do not retransmit, store or act in reliance on it or any attachments. Please notify the sender immediately if you have received this message in error. This email and any attachments have been scanned for viruses. It is the responsibility of the recipient to ensure that no viruses are contained. Zetman and its associated companies accept no responsibility for any loss or damage arising in any way from its use. Emails may be monitored for security purposes. Zetman Limited is registered in England and Wales No. 05844197. Registered office as above. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.gif Type: image/gif Size: 1627 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image002.gif Type: image/gif Size: 2775 bytes Desc: not available URL: From qwertyface at gmail.com Wed Nov 9 13:41:25 2011 From: qwertyface at gmail.com (Peter Russell) Date: Wed, 09 Nov 2011 12:41:25 -0000 Subject: [python-uk] West Yorkshire Python Group meeting - Tomorrow! Message-ID: == West Yorkshire Python User Group Meeting - Thurs. 10 Nov. == Sorry for the late announcement this month! = About the meeting = We'll be arriving at Old Broadcasting House from about 6:30 onwards for vaguely Python related chat. At 7:30 there will be a talk, which is expected to last for about an half an hour. After that we will head to a pub for more geeky chat. The meetings are always good fun, and everyone of any level of experience or interest in Python is extremely welcome. Bring a friend! = Talk: "Testing in Python" - Peter Russell = This talk was postponed last month due to lack of time. Automated testing is now an important discipline in software development. In this talk Peter will be presenting some of his views on how to test code written in Python, the virtues (or otherwise) of test driven development as a methodology, and some of the tools available for testing. Experience Level:A basic level of Python knowledge would be helpful.Of Interest to:This talk will not be a "how to test" tutorial, rather a personal perspective on testing. As such it should be of interest to people who are experienced in unit, functional and integration testing as well as people who are new to automated testing. = Date and Time = Thursday 10 November, from 6:30pm. Talk at 7:30. Pub afterwards. = Location = Old Broadcasting House 148 Woodhouse Lane Leeds LS2 9EN We will be holding the talks in the boardroom at the back of the ground floor of the building. If you arrive after 7:30 we may not hear the doorbell, so please phone Peter on 07763 570 860. = About the Group = The West Yorkshire Python User Group (WYPy) have been meeting monthly since 2007. Our meetings are free, and usually include at least one talk, as well as a trip to the pub. Our website is at http://wypy.org.uk . We discuss our meetings on the Python Yorkshire and Humberside Google Group http://groups.google.com/group/python-yorks-humber/ and you can also follow us on Twitter at @WYPython. From pythonsheffield at gmail.com Sun Nov 27 21:21:35 2011 From: pythonsheffield at gmail.com (Daley Chetwynd) Date: Sun, 27 Nov 2011 20:21:35 +0000 Subject: [python-uk] Next Python Sheffield Nov 29th Message-ID: Hi all, The next Python Sheffield meeting is being held on Tuesday November 29th at the GIST Lab in Sheffield. The meeting will run from 19:00 - 20:45, although doors will be open at the GIST Lab from 18:30. The GIST Lab is located opposite Sheffield train station and behind the Showroom cinema: http://thegisthub.net/groups/gistlab This month we have the following speaker: Peter Russell (West Yorks Python) - "Things that make Python brilliant: First-class functions and decorators" We've currently got 11 people registered for the meeting. If you'd like to join us then please register for free at: http://pysheff1111.eventbrite.co.uk We're always looking for future speakers, so if you'd like to talk on anything Python-related and fancy a trip over to Sheffield, please get in touch. To find out more about the Python Sheffield group, follow @pysheff on Twitter or see the Google group: http://groups.google.com/group/python-sheffield Thanks, Daley Chetwynd -------------- next part -------------- An HTML attachment was scrubbed... URL: From mail at timgolden.me.uk Mon Nov 28 12:27:57 2011 From: mail at timgolden.me.uk (Tim Golden) Date: Mon, 28 Nov 2011 11:27:57 +0000 Subject: [python-uk] London Python Code Dojo *this Thursday* Message-ID: <4ED3703D.8070608@timgolden.me.uk> Hi Folks, Apologies for the short notice. We were caught out by the fact that the first Thursday of the month is the first day of the month. (All right; *I* was caught out). The next London Python Code Dojo is happening this Thursday on the 1st December from 6.30pm. You can sign up here (tickets go quickly): https://ldnpydojo.eventwax.com/london-python-code-dojo-season-3-episode-4 It'll be at the offices of Fry-IT (who, at very short notice have stepped up to give us space and sponsor our pizza and beer). It'll be the usual (slightly newer) setup: beer & pizza at 6.30pm with the chance to put forward coding proposals for later. We'll start at 7.15pm with any lightning talks people may have -- please email me if you've got one you'd like to give. Then we vote on the week's coding challenge and spend a couple of hours group-coding it. At the end of the evening we show-and-tell, laugh at and with each other, and those who have any energy left head off to the pub. Where..? Fry-IT Ltd. Nearest Tubes: Waterloo Southwark Address: Fry-IT Limited 503 Enterprise House 1/2 Hatfields London SE1 9PG See you there! TJG From mail at timgolden.me.uk Wed Nov 30 13:50:05 2011 From: mail at timgolden.me.uk (Tim Golden) Date: Wed, 30 Nov 2011 12:50:05 +0000 Subject: [python-uk] London Python Code Dojo *this Thursday* In-Reply-To: <4ED3703D.8070608@timgolden.me.uk> References: <4ED3703D.8070608@timgolden.me.uk> Message-ID: <4ED6267D.60200@timgolden.me.uk> In spite of the short notice, all 30 places have now been taken for tomorrow's London Python Dojo. We often have a cancellation or two so if you want to come and didn't get there in time, drop me an email and I'll keep an eye on what's happening and let you know if a space turns up. Conversely, if you're holding a place and can't come, let me know also. Those of you who did get a ticket in time, we look forward to seeing you tomorrow at Fry-IT at 6.30pm for pizza, 7.15pm for lightning talks and coding fun. TJG