{"id":295,"date":"2011-11-08T00:54:14","date_gmt":"2011-11-08T05:54:14","guid":{"rendered":"http:\/\/wcarss.ca\/log\/?p=295"},"modified":"2011-11-08T00:54:14","modified_gmt":"2011-11-08T05:54:14","slug":"correction-i-do-know-what-subsets-are-i-swear","status":"publish","type":"post","link":"https:\/\/wcarss.ca\/log\/2011\/11\/correction-i-do-know-what-subsets-are-i-swear\/","title":{"rendered":"Correction: I do know what subsets are, I swear"},"content":{"rendered":"<p>A few months ago, I wrote a post entitled &#8220;<a href=\"http:\/\/wcarss.ca\/log\/2011\/08\/a-nice-way-to-generate-all-subsets-within-python\/\" title=\"earlier post\">A nice way to generate all subsets within python<\/a>&#8220;, and you know what? There were some issues with that post. They were pointed out to me by one <a href=\"http:\/\/codex.grimoire.ca\/\" title=\"\"Any insufficiently advanced magic is indistinguishable from technology.\"\">Owen Jacobson<\/a>, and I feel like a dork, but not the good kind &#8211; more like a fail-dork, or something. Maybe the word for that is fdork.<\/p>\n<p>Anyway, the issues, in Owen&#8217;s words, are:<\/p>\n<blockquote><p>1. from imports in functions have gone away in Python 3; I\u2019d put those at module scope, instead. The other alternative is to use import collections as c within the function and to qualify references, as with c.Iterable.<\/p>\n<p>(I know, imports within functions are an attractive idea, but the resulting semantics are very odd. The first call to a function might, or might not, alter the interpreter\u2019s global state depending on what other imports have already run, and might, or might not, take significantly longer than usual depending on how quickly imports are resolved! Not fun, as I learned to my detriment.)<\/p>\n<p>2. This seems like a great place to use generators and the yield expression. It\u2019d put the decision about whether or not to hold n! permutations in memory or simultaneously or not out in the caller\u2019s context, where there\u2019s more information to make that decision against, and it\u2019d replace four lines of code with one: return c.permute(args).<\/p>\n<p>3. Neither function actually returns all of the subsets of the set formed by their respective argument lists; they return all permutations, instead.\n<\/p><\/blockquote>\n<p>I would like to briefly respond, and by that, I mean own up. <\/p>\n<p>To the first point: neat! This makes a lot of sense &#8211; I have been staying away from reading about Python 3 at all, which is not very wise.<\/p>\n<p>To the second point: that&#8217;s really smart. It didn&#8217;t even occur to me to write this as a generator, partly because I&#8217;m not super familiar with the nitty-gritty of generators in python, but upon seeing this I am all &#8220;ohhhh, yeah&#8221;.<\/p>\n<p>Finally, to the third point: Owen is right; the code I wrote totally doesn&#8217;t produce all subsets, so what gives?!<\/p>\n<p>I believe that my initial thought was to use the &#8216;all_subsets&#8217; function (which should have been named &#8216;all_permutations&#8217; from the start) to generate all permutations of an n-bit string, which I would then use to generate all subsets. In the past, I&#8217;ve made much uglier approaches to generating every bitstring &#8212; particularly by calculating each successive permutation manually. This felt like a nice shortcut! The problem is that I only implemented half of it, and then forgot what my original thought was. And then forgot to actually think about what I was saying.<\/p>\n<p>Lessons learned: <\/p>\n<p>1. Make sure you&#8217;ve finished what you set out to do before blogging about it, or at least, make sure your posts and reality are approximately congruent.<\/p>\n<p>2. Even if a technology&#8217;s adoption (e.g. Python 3) feels infinitely distant, it isn&#8217;t too soon to become acquainted with it and to think about writing code which will be less broken when I have to update it. New technology usually exists to solve problems, and in that respect, often points to smart idioms which I can adopt now.<\/p>\n<p>3. Generators are very sensible things to use in utility functions that produce more than a single piece of data. They allow the program to move along faster, and reduce immediate storage requirements, placing the decision in the hands of the function&#8217;s user whether or not holding their full result in memory is necessary. I should read up a bit more about how to use them in Python.<\/p>\n<p>4. Owen&#8217;s pretty sharp. Thanks for the awesome response \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A few months ago, I wrote a post entitled &#8220;A nice way to generate all subsets within python&#8220;, and you know what? There were some issues with that post. They were pointed out to me by one Owen Jacobson, and I feel like a dork, but not the good kind &#8211; more like a fail-dork, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/wcarss.ca\/log\/wp-json\/wp\/v2\/posts\/295"}],"collection":[{"href":"https:\/\/wcarss.ca\/log\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wcarss.ca\/log\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wcarss.ca\/log\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wcarss.ca\/log\/wp-json\/wp\/v2\/comments?post=295"}],"version-history":[{"count":4,"href":"https:\/\/wcarss.ca\/log\/wp-json\/wp\/v2\/posts\/295\/revisions"}],"predecessor-version":[{"id":305,"href":"https:\/\/wcarss.ca\/log\/wp-json\/wp\/v2\/posts\/295\/revisions\/305"}],"wp:attachment":[{"href":"https:\/\/wcarss.ca\/log\/wp-json\/wp\/v2\/media?parent=295"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wcarss.ca\/log\/wp-json\/wp\/v2\/categories?post=295"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wcarss.ca\/log\/wp-json\/wp\/v2\/tags?post=295"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}